예제 #1
0
func BuildConnection(ws *websocket.Conn) {
	log.Info("BuildConnection()")
	token := ws.Request().URL.Query().Get("token")
	log.Debug(token)
	var uci userConnectionInfo
	err := validateToken(token, time.Now(), ws.RemoteAddr(), &uci)
	if err != nil {
		log.WithFields(log.Fields{
			"error": err,
		}).Error("validation error")
		// how should this reply to the client?
		return
	}

	onlineUser := &OnlineUser{
		Connection: ws,
		Uci:        uci,
		Send:       make(chan envelope, 256),
	}
	runningRoom.Users[onlineUser] = true
	go onlineUser.PushToClient()
	onlineUser.PullFromClient()
	delete(runningRoom.Users, onlineUser)
	log.Info("tore down user connection")
}
예제 #2
0
func (self *Server) webSocketHandler(conn *websocket.Conn) {

	dispatcher := NewDispatcher(self)

	for {
		data := map[string]interface{}{}
		err := websocket.JSON.Receive(conn, &data)

		if err != nil {
			if opErr, ok := err.(*net.OpError); ok && opErr.Timeout() {
				fmt.Println(err)
				continue
			}
			if err == io.EOF {
				fmt.Println(fmt.Sprintf("Client Dissconected :%s", conn.RemoteAddr()))
				break
			} else {
				fmt.Println(fmt.Sprintf("Receive Data Failed %s", err))
				break
			}
		}

		fmt.Println("Dispatch", data)
		err = dispatcher.Dispatch(conn, data)

		if err != nil {
			fmt.Println(fmt.Sprintf("Dispatch Failed %s", err))
		}
	}

	defer func() {
		conn.Close()
	}()

}
예제 #3
0
파일: wsserver.go 프로젝트: wiless/webplot
func socketListener(ws *websocket.Conn) {

	for {

		log.Printf("Connection Opened from %v", ws.RemoteAddr())
		activePlotter = ws
		cnt := 0
		for {

			in := bufio.NewReader(os.Stdin)
			fmt.Printf("WebPlot > ")
			str, _ := in.ReadString('\n')
			var plotcmd PlotInfo
			// log.Println("Input Command ", str)
			str = strings.TrimSpace(str)

			if strings.Contains(str, "SIN") {
				log.Printf("YOU ARE IN ", str)
				plotcmd.Type = "plot"
				plotcmd.HoldOn = (str == "SINH")
				plotcmd.Handle = 120
				plotcmd.Y = vlib.RandNFVec(100, 1)
				plotcmd.Options.Color = "red"
				plotcmd.Options.Title = fmt.Sprintf("Figure %d - (%d)", plotcmd.Handle, cnt)
				cnt++
				log.Println(plotcmd.Y)
				data, err := json.Marshal(plotcmd)

				if err != nil {
					log.Println("Err is ", err)
					break
				}
				activePlotter.Write(data)
			}

			if str == "COS" {
				plotcmd.Type = "plot"
				plotcmd.HoldOn = true
				plotcmd.Handle = rand.Intn(100)
				plotcmd.Y = vlib.RandNFVec(100, 1)
				plotcmd.Options.Color = "red"
				plotcmd.Options.Title = fmt.Sprintf("Figure %d", cnt)
				cnt++
				log.Println(plotcmd.Y)
				data, err := json.Marshal(plotcmd)

				if err != nil {
					log.Println("Err is ", err)
					break
				}
				activePlotter.Write(data)
			}

		}

	}
}
예제 #4
0
파일: websocket.go 프로젝트: huweixuan/goim
func serveWebsocket(conn *websocket.Conn) {
	var (
		// ip addr
		lAddr = conn.LocalAddr()
		rAddr = conn.RemoteAddr()
		// timer
		tr = DefaultServer.round.Timer(rand.Int())
	)
	log.Debug("start websocket serve \"%s\" with \"%s\"", lAddr, rAddr)
	DefaultServer.serveWebsocket(conn, tr)
}
예제 #5
0
func (ws *WebSocketServer) wslogsHandler(w *websocket.Conn) {
	source := w.Request().FormValue("source")
	host := fmt.Sprintf("%s/%d", w.RemoteAddr().String(), time.Now().UnixNano())

	defer func() {
		log.Printf("[%s - %s] closing websocket conn", ws.name, w.RemoteAddr().String())
		ws.b.DelSubscriber(host)
		w.Close()
	}()

	log.Printf("[%s - %s] accepting websocket conn", ws.name, w.RemoteAddr().String())

	r := make(chan *buffer.Event, recvBuffer)
	ws.b.AddSubscriber(host, r)

	for {
		select {
		case ev := <-r:
			if len(source) > 0 {
				if ev.Source != source {
					continue
				}
			}

			err := websocket.Message.Send(w, *ev.Text)
			if err != nil {
				log.Printf("[%s] error sending ws message: %v", w.RemoteAddr().String(), err.Error())
				return
			}
		}
	}
}
예제 #6
0
파일: server.go 프로젝트: nbusy/nbusy
// wsHandler handles incoming websocket connections.
func (s *Server) wsConnHandler(ws *websocket.Conn) {
	c, err := NewConn()
	if err != nil {
		log.Printf("server: error while accepting connection: %v", err)
		return
	}
	defer recoverAndLog(c, &s.wg)
	c.MiddlewareFunc(s.middleware...)

	log.Printf("server: client connected %v: %v", c.ID, ws.RemoteAddr())

	s.conns.Set(c.ID, c)
	c.setConn(ws)
	c.startReceive()
	s.conns.Delete(c.ID)
	s.disconnHandler(c)
}
예제 #7
0
파일: wsserver.go 프로젝트: wiless/webplot
// Handles commands comming from Matlab Session objects and writes to the corresponding
func handleMatlabCommands(ms *websocket.Conn) {
	log.Printf("New Mat Client %s", ms.RemoteAddr())
	io.Copy(activePlotter, ms)

	// for {
	// 	var msg []byte
	// 	msg = make([]byte, 1024)
	// 	// log.Printf("Trying to read..")
	// 	n, err := ms.Read(msg)
	// 	_ = err
	// 	if n > 0 {
	// 		log.Printf("WSServer Rx: %s", msg[0:n])
	// 		activePlotter.Write(msg)
	// 	}
	// }
	log.Println("Leaving session")
}
예제 #8
0
파일: chat.go 프로젝트: strawmang/strawmang
// HandlerChat is called in a goroutine for every connection the websocket accepts.
func HandlerChat(conn *websocket.Conn) {
	defer log.Printf("Closing websocket connection")
	log.Printf("New websocket connection")

	// reuse buffers;  keep memory usage low!
	// TODO: Look into reusing memory buffers
	buff := make([]byte, 1024)
	var event Event
	me := new(User)
	me.conn = conn
	me.Remote = conn.RemoteAddr().String()

loop:
	for {
		n, err := conn.Read(buff)
		if err != nil {
			if err == io.EOF || err == io.ErrUnexpectedEOF {
				log.Printf("[chat] EOF\n")
				conn.Close()
				break loop
			}
			GlobalServer.Errors <- err
		}

		log.Printf("Got: '%v'", string(buff[:n]))

		if err := json.Unmarshal(buff[:n], &event); err != nil {
			GlobalServer.Errors <- err
		}
		switch event.Type {
		case EVENT_NEWTOPIC:
			me.HandleNewTopic(event)
		case EVENT_MESSAGE:
			me.HandleMessage(event)
		case EVENT_LEAVE:
			me.HandleLeave(event)
		case EVENT_LOGIN:
			me.HandleLogin(event)
		case EVENT_VOTE:
			me.HandleVote(event)
		default:
			log.Printf("Unhanlded event type in user handler")
		}
	}
}
예제 #9
0
파일: chat.go 프로젝트: ZombBomb/legion
func ChatServer(ws *websocket.Conn) {
	lenBuf := make([]byte, 5)

	msgChan := make(chan *Msg, 100)
	clientKey := ws.RemoteAddr().String()
	clientRequests <- &NewClientEvent{clientKey, msgChan}
	defer func() { clientDisconnects <- clientKey }()

	go func() {
		for msg := range msgChan {
			ws.Write([]byte(msg.text))
		}
	}()
	for {
		_, err := ws.Read(lenBuf)
		if err != nil {
			log.Println("Error: ", err.Error())
			return
		}

		length, _ := strconv.Atoi(strings.TrimSpace(string(lenBuf)))
		if length > 65536 {
			log.Println("Error: too big length: ", length)
			return
		}

		if length <= 0 {
			log.Println("Empty length")
			return
		}

		buf := make([]byte, length)
		_, err = ws.Read(buf)

		if err != nil {
			log.Println("Could not read", length)
			return
		}

		messages <- &Msg{clientKey, string(buf)}
	}
}
예제 #10
0
func BuildConnection(ws *websocket.Conn) {
	token := ws.Request().URL.Query().Get("token")
	fmt.Println(token)
	var uci userConnectionInfo
	err := validateToken(token, time.Now(), ws.RemoteAddr(), &uci)
	if err != nil {
		fmt.Println("validation error: " + err.Error())
		// how should this reply to the client?
		return
	}

	onlineUser := &OnlineUser{
		Connection: ws,
		Uci:        uci,
		Send:       make(chan envelope, 256),
	}
	runningRoom.Users[onlineUser] = true
	go onlineUser.PushToClient()
	onlineUser.PullFromClient()
	delete(runningRoom.Users, onlineUser)
}
예제 #11
0
// Handles all Websocket connections
func WebHandler(ws *websocket.Conn) {
	log.Printf("WebHandler: New connection from %v", ws.RemoteAddr())

	// Create a new connection structure
	c := NewConnection(ws)

	// Notify hub to register the new connection
	DefaultHub.Register <- c

	// Defer the hub notification to unregister when this connection is closed
	defer func() {
		log.Printf("WebHandler: deferred call to remove connection from registry %v", ws.RemoteAddr())
		DefaultHub.Unregister <- c
	}()

	// Start writing in a separate goroutine
	go c.Writer()

	// Start reading from socket in the current goroutine
	c.Reader()
}
예제 #12
0
파일: tcp_server.go 프로젝트: mysll/flynet
func (c *WSClientHandler) Handle(ws *websocket.Conn) {
	if core.Closing {
		ws.Close()
		return
	}
	rwc := NewWSConn(ws)
	id := core.clientList.Add(rwc, ws.RemoteAddr().String())
	mailbox := rpc.NewMailBox(1, id, core.AppId)
	core.Emitter.Push(NEWUSERCONN, map[string]interface{}{"id": id}, true)
	cl := core.clientList.FindNode(id)
	cl.MailBox = mailbox
	cl.Run()
	codec := &ClientCodec{}
	codec.rwc = rwc
	codec.cachebuf = make([]byte, SENDBUFLEN)
	codec.node = cl
	log.LogInfo("new client:", mailbox, ",", ws.RemoteAddr())
	core.rpcServer.ServeCodec(codec, rpc.MAX_BUF_LEN)
	core.Emitter.Push(LOSTUSERCONN, map[string]interface{}{"id": cl.Session}, true)
	log.LogMessage("client handle quit")
}
예제 #13
0
func wsACMASites(ws *websocket.Conn) {
	c := &ClientConn{}
	c.ws = ws
	c.cmd = make(chan uint8)
	var cmd uint8
	log.Println("New wsACMASites Conection: ", ws.RemoteAddr())

	newConn <- c
	clients.Lock()
	clients.Clients++
	clients.Unlock()

	for {
		// read the packet
		// TODO: Reduce allocations
		packet := c.inBuffer[0:]
		n, err := ws.Read(packet)
		packet = packet[0:n]
		if err != nil {
			log.Println("wsACMASites Read Error: ", err)
			clients.Lock()
			clients.Clients--
			clients.Unlock()
			break
		}
		buf := bytes.NewBuffer(packet)
		// its all binary
		err = binary.Read(buf, binary.LittleEndian, &cmd)
		if err != nil {
			log.Println(err)
			clients.Lock()
			clients.Clients--
			clients.Unlock()
			break
		}
		// Hope this works like I think it will
		c.cmd <- cmd
	}

}
예제 #14
0
파일: websocket.go 프로젝트: xozrc/xo
func WSServe(sess session.Session, conn *websocket.Conn) {
	logger.Printf("session ip[%s] start serve\n", conn.RemoteAddr().String())
	sess.OnOpen()
	for {
		var tempContent []byte
		if err := websocket.Message.Receive(conn, &tempContent); err != nil {

			if err != io.EOF {
				logger.Printf("session ip[%s] handle data error[%s]", conn.RemoteAddr().String(), err.Error())
				sess.OnError(err)
				err = sess.Close()
				if err != nil {
					logger.Printf("session ip[%s] close error[%s]", conn.RemoteAddr().String(), err.Error())
				}
			} else {
				logger.Printf("remote ip [%s] active close\n", conn.RemoteAddr().String())
				sess.OnClose()
			}
			break
		}
		logger.Printf("receive data from %s,data [%v]\n", conn.RemoteAddr().String(), tempContent)
		sess.OnReceive(tempContent)
	}
}
예제 #15
0
파일: web.go 프로젝트: raybejjani/gitsync
// makeWebsocketName composes an identifier for a websocket client
func makeWebsocketName(ws *websocket.Conn) string {
	return fmt.Sprintf("[%p]%s", ws, ws.RemoteAddr())
}
예제 #16
0
func renderServer(ws *websocket.Conn) {
	addr := ws.RemoteAddr()
	log.Println("new connection:", addr)
	defer func() { log.Println(addr, "was disconnected") }()

	// Setup watchdog.
	shutdownWatch := make(chan struct{}, 1)
	defer func() { shutdownWatch <- struct{}{} }()
	go func() {
		select {
		case <-shutdownWatch:
		case <-time.After(time.Duration(arguments.timeout) * time.Minute):
			log.Println("session timeout")
			ws.Close()
		}
	}()

	var setup setupMessage
	if err := messageCodec.Receive(ws, &setup); err != nil {
		log.Println(err)
		return
	}
	log.Println(setup)

	if setup.Resolution < 16 || setup.Resolution > 4096 {
		log.Println("invalid setup")
		return
	}

	var (
		surfaces   [6]*image.RGBA
		raytracers [6]*trace.Raytracer
		cameras    [6]lookAtCamera

		rect = image.Rect(0, 0, setup.Resolution, setup.Resolution)
	)

	for i, _ := range surfaces {
		surfaces[i] = image.NewRGBA(rect)

		cfg := trace.Config{
			FieldOfView:   1.55,
			TreeScale:     1,
			ViewDist:      float32(arguments.viewDistance),
			Images:        [2]*image.RGBA{surfaces[i], nil},
			Jitter:        false,
			MultiThreaded: true,
		}

		raytracers[i] = trace.NewRaytracer(cfg)
		clear := setup.ClearColor
		raytracers[i].SetClearColor(color.RGBA{clear[0], clear[1], clear[2], clear[3]})

		cameras[i] = cameraMatrix[i]
	}

	updateChan := make(chan updateMessage, 2)

	go func() {
		var update updateMessage
		for {
			if err := messageCodec.Receive(ws, &update); err != nil {
				log.Println(err)
				return
			}

			// TODO Verify message.
			updateChan <- update
		}
	}()

	for {
		update := <-updateChan
		for i := 0; i < 6; i++ {
			camera := cameras[i]
			camera.pos = update.Position
			camera.at[0] += camera.pos[0]
			camera.at[1] += camera.pos[1]
			camera.at[2] += camera.pos[2]

			raytracers[i].Trace(&camera, loadedTree.tree, loadedTree.maxDepth)
		}

		for _, rt := range raytracers {
			if err := streamCodec.Send(ws, rt.Image(0).Pix); err != nil {
				log.Println(err)
				return
			}
		}
	}
}
예제 #17
0
파일: apiclient_test.go 프로젝트: bac/juju
func assertConnAddrForModel(c *gc.C, conn *websocket.Conn, addr, modelUUID string) {
	c.Assert(conn.RemoteAddr().String(), gc.Equals, "wss://"+addr+"/model/"+modelUUID+"/api")
}
예제 #18
0
func renderServer(ws *websocket.Conn) {
	addr := ws.RemoteAddr()
	log.Println("new connection:", addr)
	defer func() { log.Println(addr, "was disconnected") }()

	// Setup watchdog.
	shutdownWatch := make(chan struct{}, 1)
	defer func() { shutdownWatch <- struct{}{} }()
	go func() {
		select {
		case <-shutdownWatch:
		case <-time.After(time.Duration(arguments.timeout) * time.Minute):
			log.Println("session timeout")
			ws.Close()
		}
	}()

	var setup setupMessage
	if err := messageCodec.Receive(ws, &setup); err != nil {
		log.Println(err)
		return
	}
	log.Println(setup)

	if setup.Width*setup.Height > 1280*720 || setup.FieldOfView < 45 || setup.FieldOfView > 180 {
		log.Println("invalid setup")
		log.Println(setup)
		return
	}

	rect := image.Rect(0, 0, setup.Width/2, setup.Height)
	backBuffer := image.NewPaletted(rect, loadedTree.pal)
	surfaces := [2]*image.RGBA{
		image.NewRGBA(rect),
		image.NewRGBA(rect),
	}

	cfg := trace.Config{
		FieldOfView:   setup.FieldOfView,
		TreeScale:     1,
		ViewDist:      float32(arguments.viewDistance),
		Images:        surfaces,
		Jitter:        true,
		MultiThreaded: true,
		FrameSeed:     1,
	}

	raytracer := trace.NewRaytracer(cfg)
	clear := setup.ClearColor
	raytracer.SetClearColor(color.RGBA{clear[0], clear[1], clear[2], clear[3]})
	updateChan := make(chan updateMessage, 2)

	go func() {
		var update updateMessage
		for {
			if err := messageCodec.Receive(ws, &update); err != nil {
				log.Println(err)
				return
			}

			// TODO Verify message.
			updateChan <- update
		}
	}()

	// Send palette.
	if setup.ColorFormat == "PALETTED" {
		log.Println("sending palette...")
		if err := streamCodec.Send(ws, loadedTree.rawPal); err != nil {
			log.Println(err)
			return
		}
	}

	for {
		update := <-updateChan
		camera := trace.FreeFlightCamera{
			Pos:  update.Camera.Position,
			XRot: update.Camera.XRot,
			YRot: update.Camera.YRot,
		}

		frame := 1 + raytracer.Trace(&camera, loadedTree.tree, loadedTree.maxDepth)
		idx := frame % 2

		var err error
		if setup.ColorFormat == "PALETTED" {
			draw.Draw(backBuffer, rect, raytracer.Image(idx), image.ZP, draw.Src)
			err = streamCodec.Send(ws, backBuffer.Pix)
		} else {
			err = streamCodec.Send(ws, raytracer.Image(idx).Pix)
		}

		if err != nil {
			log.Println(err)
			return
		}
	}
}
예제 #19
0
func assertConnAddrForEnv(c *gc.C, conn *websocket.Conn, addr, envUUID, tail string) {
	c.Assert(conn.RemoteAddr(), gc.Matches, "^wss://"+addr+"/environment/"+envUUID+tail+"$")
}
예제 #20
0
파일: wsserver.go 프로젝트: wiless/webplot
func socketListener(ws *websocket.Conn) {

	// var fa FeedArray
	// SubscriberLists[ws] = fa
	for {

		log.Printf("Connection Opened from %v", ws.RemoteAddr())
		activePlotter = ws
		cnt := 0
		for {

			in := bufio.NewReader(os.Stdin)
			fmt.Printf("Enter Message : ")
			str, _ := in.ReadString('\n')
			var plotcmd PlotInfo
			log.Println("Input Command ", str)
			str = strings.TrimSpace(str)

			if strings.Contains(str, "SIN") {
				log.Printf("YOU ARE IN ", str)
				plotcmd.Type = "plot"
				plotcmd.HoldOn = (str == "SINH")
				plotcmd.Handle = 120
				plotcmd.Y = vlib.RandNFVec(100, 1)
				plotcmd.Options.Color = "red"
				plotcmd.Options.Title = fmt.Sprintf("Figure %d - (%d)", plotcmd.Handle, cnt)
				cnt++
				log.Println(plotcmd.Y)
				data, err := json.Marshal(plotcmd)

				if err != nil {
					log.Println("Err is ", err)
					break
				}
				activePlotter.Write(data)
			}

			if str == "COS" {
				plotcmd.Type = "plot"
				plotcmd.HoldOn = true
				plotcmd.Handle = rand.Intn(100)
				plotcmd.Y = vlib.RandNFVec(100, 1)
				plotcmd.Options.Color = "red"
				plotcmd.Options.Title = fmt.Sprintf("Figure %d", cnt)
				cnt++
				log.Println(plotcmd.Y)
				data, err := json.Marshal(plotcmd)

				if err != nil {
					log.Println("Err is ", err)
					break
				}
				activePlotter.Write(data)
			}

		}
		// {

		// for {
		// 	msg := make([]byte, 1024)
		// 	n, _ := ws.Read(msg)
		// 	if n > 0 {
		// 		log.Printf("Read Message  %s", msg[:n])

		// 		var f FeedInfo
		// 		jerr := json.Unmarshal(msg[0:n], &f)
		// 		if jerr == nil {
		// 			fa = append(fa, f)
		// 			SubscriberLists[ws] = fa
		// 			log.Printf("Updated subscriptions for %v with %v ", ws.RemoteAddr(), fa)
		// 		} else {
		// 			fmt.Println("Error in Unmarshalling ", jerr, " See text ", string(msg[:n]))
		// 			f.ID = 0
		// 			f.FieldNames = []string{"Dummy"}
		// 			fa = append(fa, f)
		// 			SubscriberLists[ws] = fa
		// 			log.Printf("DUMMY Updated subscriptions (%v) for %v with %v ", ws, ws.RemoteAddr(), fa)

		// 		}
		// 	}

		// }
		// }

	}
}
예제 #21
0
func webSocketHandler(ws *websocket.Conn) {
	log.Println(fmt.Sprintf("websocket | receive incoming ws connection -> %s", ws.RemoteAddr()))
	wrap := webSocketWrapper{ws: ws, close: make(chan bool)}
	conChan <- &wrap
	<-wrap.close // don't return to avoid closing the connection. Let the client close it!
}
예제 #22
0
func assertConnAddrForRoot(c *gc.C, conn *websocket.Conn, addr string) {
	c.Assert(conn.RemoteAddr(), gc.Matches, "^wss://"+addr+"/$")
}
예제 #23
0
파일: apiclient_test.go 프로젝트: OSBI/juju
func assertConnAddrForEnv(c *gc.C, conn *websocket.Conn, addr, modelUUID, tail string) {
	c.Assert(conn.RemoteAddr(), gc.Matches, "^wss://"+addr+"/model/"+modelUUID+tail+"$")
}
예제 #24
0
파일: client.go 프로젝트: mysll/flynet
func (hd *wshandler) Handle(conn *websocket.Conn) {

	log.LogInfo("new websocket client: ", conn.RemoteAddr())

	if !App.MustAppReady {
		log.LogError("must app not ready")
		conn.Close()
		return
	}

	r := &s2c.Rpc{}
	r.Sender = proto.String(App.Name)

	h, p, err := GetLogin()
	if err != nil {
		e := &s2c.Error{}
		e.ErrorNo = proto.Int32(share.ERROR_NOLOGIN)
		b, err := proto.Marshal(e)
		if err != nil {
			conn.Close()
			log.LogFatalf(err)
		}

		r.Servicemethod = proto.String("Login.Error")
		r.Data = b
		data, err := proto.Marshal(r)
		if err != nil {
			log.LogFatalf(err)
			return
		}
		out, _ := util.CreateMsg(nil, data, share.S2C_RPC)
		err = websocket.Message.Send(conn, out)
		if err != nil {
			conn.Close()
			log.LogError(err)
			return
		}
	} else {
		l := &s2c.Login{}
		l.Host = proto.String(h)
		l.Port = proto.Int32(int32(p))
		b, err := proto.Marshal(l)
		if err != nil {
			conn.Close()
			log.LogFatalf(err)
		}
		log.LogInfo("client choose login:"******":", p)

		r.Servicemethod = proto.String("Login.LoginInfo")
		r.Data = b
		data, err := proto.Marshal(r)
		if err != nil {
			log.LogFatalf(err)
			return
		}
		out, _ := util.CreateMsg(nil, data, share.S2C_RPC)
		err = websocket.Message.Send(conn, out)
		if err != nil {
			conn.Close()
			log.LogError(err)
			return
		}
	}
	conn.SetReadDeadline(time.Now().Add(time.Second * 10))
	websocket.Message.Receive(conn, hd.ignore[:])
	log.LogMessage("client close: ", conn.RemoteAddr())
	conn.Close()
}
예제 #25
0
파일: map.go 프로젝트: besserIO/thegridgame
/*
* Regions are tied to a websocket. Each new socket defines a new region.. no other "security"
*
 */
func (c Map) Socket(region int, ws *websocket.Conn) revel.Result {
	revel.INFO.Println("Bridge.Socket().Connect", region)

	//Check to see if this IP address is requesting too many resources
	//remoteAddr := strings.Split(ws.RemoteAddr.String(),":")[0]
	//
	// WTF, this doesnt return what it should.
	// Revel bug. Problems.
	//
	revel.INFO.Println("Bridge.Socket().Connect", c.Request.RemoteAddr)
	revel.INFO.Println("Bridge.Socket().Connect", ws.RemoteAddr().String())
	//

	//Connect to the backend update channel
	subscription := app.Subscribe()
	defer subscription.Cancel()

	//Allocate a region to this channel
	region, err := app.Arena.Hack(region)
	defer app.Arena.Unhack(region)
	if err != nil {
		revel.INFO.Println("Bridge.Socket().Hacking", err)
	}
	if websocket.JSON.Send(ws, &map[string]int{"region": region}) != nil {
		// They disconnected.
		revel.INFO.Println("Bridge.Socket()", region, "disconnected")
		return nil
	}

	//channel to pass information between websocket handler and main websocket look
	fromUser := make(chan app.NodeState, 10)
	//Handler of input from websocket
	go func() {
		//even though we accept the region component of app.NodeState, we will ignore it
		var msg app.NodeState

		//cleanup when the websocket dies
		defer close(fromUser)

		//don't allow people to spam the socket, so stick limit on requests-per-time
		lastEvent := time.Now()
		for {
			//automagically format recieved messages into the appropriate format.
			if websocket.JSON.Receive(ws, &msg) != nil {
				//Kill the socket if this fails. Don't f**k it up.
				return
			}
			//spam control
			if time.Since(lastEvent) > time.Duration(SPAMCONTROL) {
				//pass to main loop
				fromUser <- msg
				//reset time
				lastEvent = time.Now()
			}
		}
	}()

	//main websocket handler loop
	for i := 0; ; i++ {
		select {
		//wait for new events, ie all the updates for all the nodes
		case event := <-subscription.New: //new "Message" from subscription
			//
			//revel.INFO.Println("Bridge.Socket() sample data", event[0])
			if websocket.JSON.Send(ws, &event) != nil {
				// They disconnected.
				revel.INFO.Println("Bridge.Socket()", region, "disconnected")
				return nil
			}
		//events from the user requesting changes
		case msg, ok := <-fromUser:
			// If the channel is closed, they disconnected.
			revel.INFO.Println("Bridge.Socket() cyberhack control:", region, msg.Frq)

			if !ok {
				revel.INFO.Println("Bridge.Socket()", region, "disconnected")
				return nil
			}

			//Force the region to be what this websocket controls
			msg.Id = region
			//msg.Status = true
			//msg.P = 10000
			app.ClientEvents <- msg
		}
	}
	return nil
}