예제 #1
0
func (vars V) sendmessage(message interface{}, c websocket.Codec) {
	ws := vars.GetSocket()
	c.Send(ws, message)
}
예제 #2
0
func WSGlassHandler(c *websocket.Conn) {
	defer c.Close()
	fmt.Println("Connected with glass")
	path := strings.Split(c.Request().URL.Path, "/")
	if len(path) != 4 {
		fmt.Println("Bad path")
		WSSend(c, &[]interface{}{[]uint8("error"), []uint8("Bad url path")})
		return
	}
	userId, err := getSecretUser("ws", secretHash(path[len(path)-1]))
	if err != nil {
		fmt.Println(err)
		WSSend(c, &[]interface{}{[]uint8("error"), []uint8("Invalid credentials please setup glass")})
		return
	}
	userId = SanitizeUserId(userId)
	svc, err := mirror.New(authTransport(userId).Client())
	if err != nil {
		LogPrintf("ws: mirror")
		WSSend(c, &[]interface{}{[]uint8("error"), []uint8("Unable to create mirror transport")})
		return
	}
	// TODO: make buffer size configurable
	if Locks[userId] == nil {
		Locks[userId] = &sync.Mutex{}
	}
	Locks[userId].Lock()
	wsSendChan := make(chan *[]interface{}, 5)
	DeviceChannels[userId] = append(DeviceChannels[userId], wsSendChan)
	Locks[userId].Unlock()
	WSUpdateConnections(userId)
	wsSendChan <- &[]interface{}{[]uint8("version"), version}
	if ravenDSN != "" {
		wsSendChan <- &[]interface{}{[]uint8("raven"), []uint8(ravenDSN)}
	}
	defer func() {
		Locks[userId].Lock()
		var p []chan *[]interface{}
		for _, v := range DeviceChannels[userId] {
			if v != wsSendChan {
				p = append(p, v)
			}
		}
		DeviceChannels[userId] = p
		Locks[userId].Unlock()
		WSUpdateConnections(userId)
	}()
	var latestSensors, latestImage *[]interface{}

	// Initialize delays
	die := false

	// Websocket sender
	go func() {
		for {
			request, ok := <-wsSendChan
			if !ok {
				die = true
				break
			}
			fmt.Println("Sending to glass")
			msgcodec := websocket.Codec{MsgpackMarshal, MsgpackUnmarshal}
			err = msgcodec.Send(c, request)
			if err != nil {
				die = true
				break
			}
		}
	}()

	// Data from glass loop
	for {
		request := []interface{}{}
		requestP := &request
		msgcodec := websocket.Codec{MsgpackMarshal, MsgpackUnmarshal}
		err := msgcodec.Receive(c, &request)
		if err != nil {
			LogPrintf("ws: from glass")
			fmt.Println(err)
			die = true
			close(wsSendChan)
			break
		}
		if die {
			break
		}
		action := string(request[0].([]uint8))
		//fmt.Println(action)
		if action == "timeline" {
			ti := mirror.TimelineItem{}
			err = json.Unmarshal(request[1].([]uint8), &ti)
			if err != nil {
				LogPrintf("ws: timeline: js")
				continue
			}
			req := svc.Timeline.Insert(&ti)
			//req.Media(strings.NewReader(image))
			_, err := req.Do()
			if err != nil {
				LogPrintf("ws: timeline: send")
				continue
			}
		} else if action == "log" {
			fmt.Println(request[1].([]uint8))
			WSSendWeb(userId, &requestP)
		} else if action == "sensors" {
			latestSensors = requestP
			WSSendWeb(userId, &latestSensors)
		} else if action == "image" {
			latestImage = requestP
			WSSendWeb(userId, &latestImage)
		} else if strings.HasPrefix(action, "gist_") {
			responseGH := GithubGistHandle(userId, request)
			if responseGH != nil {
				wsSendChan <- responseGH
			}
		} else {
			WSSendWeb(userId, &requestP)
		}
	}
}
예제 #3
0
func WSSend(c *websocket.Conn, request *[]interface{}) error {
	msgcodec := websocket.Codec{MsgpackMarshal, MsgpackUnmarshal}
	return msgcodec.Send(c, request)
}
예제 #4
0
func WSWebHandler(c *websocket.Conn) {
	defer c.Close()
	userId, err := userID(c.Request())
	if err != nil || userId == "" {
		path := strings.Split(c.Request().URL.Path, "/")
		if len(path) != 4 {
			fmt.Println("Bad path")
			return
		}
		userId, err = getSecretUser("client", secretHash(path[len(path)-1]))
		if err != nil {
			fmt.Println(err)
			return
		}
	}
	userId = SanitizeUserId(userId)
	fmt.Println("Websocket connected")
	// TODO: make buffer size configurable
	if Locks[userId] == nil {
		Locks[userId] = &sync.Mutex{}
	}
	die := false
	Locks[userId].Lock()
	wsSendChan := make(chan **[]interface{}, 5)
	WebChannels[userId] = append(WebChannels[userId], wsSendChan)
	Locks[userId].Unlock()
	WSUpdateConnections(userId)
	versionRequestP := &[]interface{}{[]uint8("version"), version}
	wsSendChan <- &versionRequestP
	if ravenDSN != "" {
		ravenRequestP := &[]interface{}{[]uint8("raven"), []uint8(ravenDSN)}
		wsSendChan <- &ravenRequestP
	}
	defer func() {
		Locks[userId].Lock()
		var p []chan **[]interface{}
		for _, v := range WebChannels[userId] {
			if v != wsSendChan {
				p = append(p, v)
			}
		}
		WebChannels[userId] = p
		Locks[userId].Unlock()
		WSUpdateConnections(userId)
	}()
	var lastSensors, lastImage *[]interface{}
	// Websocket sender
	go func() {
		for {
			request, ok := <-wsSendChan
			if !ok || die {
				break
			}
			msgcodec := websocket.Codec{MsgpackMarshal, MsgpackUnmarshal}
			action := string((**request)[0].([]uint8))
			/* NOTE(brandyn): This assumes that the pointer changes between samples,
			   I believe this is safe and it greatly simplifies sending the latest image/sensors.
			   If this doesn't hold, then we would only miss sending a sample so the harm is minimal.
			*/
			if action == "image" {
				if *request == lastImage {
					fmt.Println("Already sent image, skipping")
					continue
				}
				lastImage = *request
			} else if action == "sensors" {
				if *request == lastSensors {
					fmt.Println("Already sent sensors, skipping")
					continue
				}
				lastSensors = *request
			}
			err := msgcodec.Send(c, **request)
			if err != nil {
				return
			}
		}
	}()
	// Data from web loop
	for {
		request := []interface{}{}
		msgcodec := websocket.Codec{MsgpackMarshal, MsgpackUnmarshal}
		err := msgcodec.Receive(c, &request)
		if err != nil {
			fmt.Println(err)
			die = true
			close(wsSendChan)
			return
		}
		action := string(request[0].([]uint8))
		fmt.Println(action)
		if action == "signScript" {
			scriptBytes, err := SignatureSignScript(userId, request[1].([]byte))
			if err != nil {
				LogPrintf("notify: request")
				continue
			}
			request[1] = scriptBytes
			requestP := &request
			wsSendChan <- &requestP
		} else if strings.HasPrefix(action, "gist_") {
			responseGH := GithubGistHandle(userId, request)
			if responseGH != nil {
				wsSendChan <- &responseGH
			}
		} else {
			WSSendDevice(userId, &request)
		}
	}
}
예제 #5
0
func WSGlassHandler(c *websocket.Conn) {
	defer c.Close()
	fmt.Println("Connected with glass")
	path := strings.Split(c.Request().URL.Path, "/")
	if len(path) != 4 {
		fmt.Println("Bad path")
		return
	}
	userId, err := getSecretUser("ws", secretHash(path[len(path)-1]))
	if err != nil {
		fmt.Println(err)
		return
	}
	uflags, err := getUserFlags(userId, "uflags")
	if err != nil {
		fmt.Println(fmt.Errorf("Couldn't get flags: %s", err))
		return
	}
	svc, err := mirror.New(authTransport(userId).Client())
	if err != nil {
		LogPrintf("ws: mirror")
		return
	}
	// TODO: Look into locking and add defer to cleanup later, make buffer size configurable
	wsSendChan := make(chan *[]interface{}, 5)
	wsSendChan <- &[]interface{}{[]uint8("version"), version}
	DeviceChannels[userId] = append(DeviceChannels[userId], wsSendChan)
	visionChan := make(chan *[]interface{})
	var latestSensors, latestImage *[]interface{}

	// Initialize delays
	die := false

	// Websocket sender
	go func() {
		for {
			request, ok := <-wsSendChan
			if !ok {
				die = true
				break
			}
			fmt.Println("Sending to glass")
			msgcodec := websocket.Codec{MsgpackMarshal, MsgpackUnmarshal}
			err = msgcodec.Send(c, request)
			if err != nil {
				die = true
				break
			}
		}
	}()

	// Flags sender
	go func() {
		for {
			if die {
				break
			}
			// TODO: Make a subscription and have this repeated only when things change
			uflags, err = getUserFlags(userId, "uflags")
			if err != nil {
				fmt.Println(fmt.Errorf("Couldn't get flags: %s", err))
				time.Sleep(time.Millisecond * 2000)
				continue
			}
			fmt.Println("Sending flags")
			wsSendChan <- &[]interface{}{"flags", uflags}
			time.Sleep(time.Millisecond * 2000)
		}
	}()

	// Vision
	go func() {
		for {
			request, ok := <-visionChan
			if !ok {
				die = true
				break
			}
			input := string((*request)[3].([]uint8))
			output := process_image(&input)
			if output != nil {
				WSSendDevice(userId, &[]interface{}{[]uint8("image"), (*request)[1], (*request)[2], []uint8(*output)})
			}
		}
	}()

	// Data from glass loop
	for {
		request := []interface{}{}
		requestP := &request
		msgcodec := websocket.Codec{MsgpackMarshal, MsgpackUnmarshal}
		err := msgcodec.Receive(c, &request)
		if err != nil {
			LogPrintf("ws: from glass")
			fmt.Println(err)
			die = true
			break
		}
		if die {
			break
		}
		action := string(request[0].([]uint8))
		fmt.Println(action)
		if action == "timeline" {
			ti := mirror.TimelineItem{}
			err = json.Unmarshal(request[1].([]uint8), &ti)
			if err != nil {
				LogPrintf("ws: timeline: js")
				continue
			}
			req := svc.Timeline.Insert(&ti)
			//req.Media(strings.NewReader(image))
			_, err := req.Do()
			if err != nil {
				LogPrintf("ws: timeline: send")
				continue
			}
		} else if action == "log" {
			fmt.Println(request[1].([]uint8))
			WSSendWeb(userId, &requestP)
		} else if action == "sensors" {
			latestSensors = requestP
			WSSendWeb(userId, &latestSensors)
		} else if action == "image" {
			latestImage = requestP
			WSSendWeb(userId, &latestImage)
			select {
			case visionChan <- requestP:
			default:
				fmt.Println("Image skipped vision processing, it was busy...")
			}
		} else {
			WSSendWeb(userId, &requestP)
		}
	}
}
예제 #6
0
func WSWebHandler(c *websocket.Conn) {
	defer c.Close()
	userId, err := userID(c.Request())
	if err != nil || userId == "" {
		path := strings.Split(c.Request().URL.Path, "/")
		if len(path) != 4 {
			fmt.Println("Bad path")
			return
		}
		userId, err = getSecretUser("ws", secretHash(path[len(path)-1]))
		if err != nil {
			fmt.Println(err)
			return
		}
	}
	fmt.Println("Websocket connected")
	// TODO: Look into locking and add defer to cleanup later, make buffer size configurable
	// TODO: This needs the "die" code added, look into glass side also
	wsSendChan := make(chan **[]interface{}, 5)
	versionRequestP := &[]interface{}{[]uint8("version"), version}
	wsSendChan <- &versionRequestP
	WebChannels[userId] = append(WebChannels[userId], wsSendChan)
	var lastSensors, lastImage *[]interface{}
	// Websocket sender
	go func() {
		for {
			request, ok := <-wsSendChan
			if !ok {
				break
			}
			msgcodec := websocket.Codec{MsgpackMarshal, MsgpackUnmarshal}
			action := string((**request)[0].([]uint8))
			/* NOTE(brandyn): This assumes that the pointer changes between samples,
			   I believe this is safe and it greatly simplifies sending the latest image/sensors.
			   If this doesn't hold, then we would only miss sending a sample so the harm is minimal.
			*/
			if action == "image" {
				if *request == lastImage {
					fmt.Println("Already sent image, skipping")
					continue
				}
				lastImage = *request
			} else if action == "sensors" {
				if *request == lastSensors {
					fmt.Println("Already sent sensors, skipping")
					continue
				}
				lastSensors = *request
			}
			err := msgcodec.Send(c, **request)
			if err != nil {
				return
			}
		}
	}()
	// Data from web loop
	for {
		request := []interface{}{}
		msgcodec := websocket.Codec{MsgpackMarshal, MsgpackUnmarshal}
		err := msgcodec.Receive(c, &request)
		if err != nil {
			fmt.Println(err)
			return
		}
		action := string(request[0].([]uint8))
		fmt.Println(action)
		if action == "sendTimelineImage" {
			trans := authTransport(userId)
			if trans == nil {
				LogPrintf("notify: auth")
				continue
			}
			svc, err := mirror.New(trans.Client())
			if err != nil {
				LogPrintf("notify: mirror")
				continue
			}
			sendImageCard(request[1].(string), "", svc)
		} else if action == "signScript" {
			scriptBytes, err := SignatureSignScript(userId, request[1].([]byte))
			if err != nil {
				LogPrintf("notify: request")
				continue
			}
			request[1] = scriptBytes
			requestP := &request
			wsSendChan <- &requestP
		} else {
			WSSendDevice(userId, &request)
		}
	}
}