func newClient(ws *websocket.Conn, h *hub, srv *wsServer) *wsClient { if ws == nil { log.Panicln("ws cannot be nil") } if srv == nil { log.Panicln("server cannot be nil") } maxID++ return &wsClient{ id: maxID, ws: ws, h: h, srv: srv, subs: make(map[string]string), inMsgChan: make(chan *wsMessage), outMsgChan: make(chan *wsMessage), doneChan: make(chan bool), socketID: sha1Sum(fmt.Sprintf("%s-%s-%d", ws.RemoteAddr().String(), ws.LocalAddr().String(), maxID)), } }
func (g *Group) AddClient(ws *websocket.Conn) *Client { if len(g.Clients) > g.MaxClients { return nil } g.Lock() g.CurrentId++ c := new(Client) c.Id = g.CurrentId c.Conn = ws c.Addr = ws.LocalAddr().String() c.CurGroup = g g.Clients[c.Id] = c g.Unlock() c.On_Login() return c }
func (m *Master) Listen(ws *websocket.Conn) { logger.Printf("Listen(%v): node connecting", ws.LocalAddr().String()) nh := NewNodeHandle(NewConnection(ws, false), m) logger.Printf("Adding Node to Map (%v)", ws.LocalAddr().String()) m.nodeMu.Lock() m.NodeHandles[nh.NodeId] = nh m.nodeMu.Unlock() logger.Printf("Calling Remove Node on Death (%v)", ws.LocalAddr().String()) go m.RemoveNodeOnDeath(nh) for i := 0; i < iomonitors; i++ { logger.Printf("Starting IOMonitor %v (%v)", i, ws.LocalAddr().String()) go nh.MonitorIO() } logger.Printf("Starting Monitor (%v)", ws.LocalAddr().String()) nh.Monitor() }
func (self *Handler) WSSocketHandler(ws *websocket.Conn) { sock := &WWS{ Socket: ws, Logger: self.logger, Born: time.Now(), Quit: false} defer func(logger *util.HekaLogger) { if r := recover(); r != nil { debug.PrintStack() if logger != nil { logger.Error(self.logCat, "Uknown Error", util.Fields{"error": r.(error).Error()}) } else { log.Printf("Socket Unknown Error: %s\n", r.(error).Error()) } } }(sock.Logger) // get the device id from the localAddress: Url, err := url.Parse(ws.LocalAddr().String()) if err != nil { self.logger.Error(self.logCat, "Unparsable URL for websocket", util.Fields{"error": err.Error()}) return } elements := strings.Split(Url.Path, "/") var deviceId string if len(elements) < 3 { self.logger.Error(self.logCat, "No deviceID found", util.Fields{"error": err.Error(), "path": Url.Path}) return } deviceId = elements[3] // Kill the old client. if client, ok := Clients[deviceId]; ok { client.Quit = true } self.metrics.Increment("Socket") Clients[deviceId] = sock sock.Run() self.metrics.Decrement("Socket") }
/* pings the server with a message; closes socket */ func ping(sock *websocket.Conn) { fmt.Println("user connected on page <" + sock.LocalAddr().String() + ".html> from <" + sock.Request().RemoteAddr + ">") /* array of bytes for a buffer */ buf := make([]byte, 1024) /* read, error check */ r, err := sock.Read(buf) if err != nil { panic("Read: " + err.Error()) } /* print size and what was read */ fmt.Println("Read", r, "bytes") fmt.Println(string(buf)) _, err = sock.Write([]byte("OK")) if err != nil { panic("Read: " + err.Error()) } sock.Close() }
func wsHandler(ws *websocket.Conn) { url := strings.Split(fmt.Sprintf("%s", ws.LocalAddr()), "/") id := url[len(url)-1] peer := plong.FindPrivatePeer(id) if peer.PrivateId == "" { fmt.Printf("[WebSocket] Error: No such peer “%s”.\n", id) return } c := &Connection{send: make(chan string, BufferSize), ws: ws, peer: peer} wsHub.Add(c) fmt.Printf("[WebSocket] New connection: “%s”.\n", id) defer func() { wsHub.Remove(c) }() go c.Writer() c.Reader() }
func parseCommand(sock *websocket.Conn) { fmt.Println("user connected on page <" + sock.LocalAddr().String() + "> from <" + sock.Request().RemoteAddr + ">") reader := bufio.NewReader(sock) writer := bufio.NewWriter(sock) /* varaibles for username and logged_in status */ var username string var logged_in = false /* loop until login */ for !logged_in { /* block until a line is read */ line, err := reader.ReadString('\n') /* if socket closed return from thread */ if closed_sock(err) { break } /* trim off the command then trim out the spaces, username is left */ if !strings.HasPrefix(line, "ME IS") { writeToBuf("ERROR invalid: must login first\n", writer) continue } line = strings.TrimPrefix(line, "ME IS") username = strings.TrimSpace(line) /* username must not contain spaces * username must not be in use * login user if valid */ if strings.Contains(username, " ") { writeToBuf("ERROR username cannot contain spaces\n", writer) } else if _, exists := users[username]; exists { writeToBuf("ERROR username in use already\n", writer) } else { users[username] = writer logged_in = true writeToBuf("OK user logged in\n", writer) } /* loop back again */ } /* loop until disconnect/logout */ for logged_in { /* read the next line */ line, err := reader.ReadString('\n') if closed_sock(err) { break } /* parse through options; trim prefix, get username, process command */ /* list all users connected */ if strings.HasPrefix(line, "WHO HERE") { line = strings.TrimPrefix(line, "WHO HERE") in_name := strings.TrimSpace(line) if in_name != username { writeToBuf("ERROR name with command mismatch\n", writer) continue } /* add all users to the bufferWriter then flush to send */ for name, _ := range users { writer.WriteString(name + " ") } writer.Flush() /* send to all users */ } else if strings.HasPrefix(line, "BROADCAST") { line = strings.TrimPrefix(line, "BROADCAST") in_name := strings.TrimSpace(line) if in_name != username { writeToBuf("ERROR name with command mismatch\n", writer) continue } /* get size of bytes */ line, err = reader.ReadString('\n') if closed_sock(err) { break } size, err := strconv.Atoi(strings.TrimSpace(line)) if size == 0 || err != nil { writeToBuf("ERROR invalid message size\n", writer) continue } buf := make([]byte, size) for i := 0; i < size; i++ { buf[i], err = reader.ReadByte() if err != nil { panic("ReadByte(broadcast)" + err.Error()) } } /* write to all users */ for _, b_out := range users { writeToBuf("FROM "+username+"\n"+line+string(buf), b_out) } /* logout user */ } else if strings.HasPrefix(line, "LOGOUT") { line = strings.TrimPrefix(line, "LOGOUT") in_name := strings.TrimSpace(line) if in_name != username { writeToBuf("ERROR invalid logout request\n", writer) continue } /* remove from map and close socket */ delete(users, username) writeToBuf("OK user logged out\n", writer) logged_in = false /* cant log in again */ } else if strings.HasPrefix(line, "ME IS") { writeToBuf("ERROR already logged in on this connection\n", writer) /* not a valid command */ } else { writeToBuf("ERROR invalid command\n", writer) } /* re loop for next read */ } sock.Close() fmt.Println("Closed socket " + sock.Request().RemoteAddr) }
/* echo it back */ func Echo(sock *websocket.Conn) { fmt.Println("echo conn on page <" + sock.LocalAddr().String() + ".html> from <" + sock.Request().RemoteAddr + ">") io.Copy(sock, sock) }