This demo implements:
- Message broadcasting
- Heartbeat detection
Chat via command line
The specific logic is in websocket.go
The core here is the global variable aliveList, which is responsible for distributing messages to clients. Events are passed through channel s to reduce blocking
A single link will be registered in the Livelist, and ConnList is all the active links
// Livelist current online list type AliveList struct { ConnList map[string]*Client register chan *Client destroy chan *Client broadcast chan Message cancel chan int Len int } // Client socket client type Client struct { ID string conn *websocket.Conn cancel chan int }
An event listening cycle will be executed after the service is started
// lsnrctl start func (al *AliveList) run() { log.Println("Start listening for registration events") for { select { case client := <-al.register: log.Println("Registration event:", client.ID) al.ConnList[client.ID] = client al.Len++ al.SysBroadcast(ConnectedMessage, Message{ ID: client.ID, Content: "connected", SentAt: time.Now().Unix(), }) case client := <-al.destroy: log.Println("Destruction event:", client.ID) err := client.conn.Close() if err != nil { log.Printf("destroy Error: %v \n", err) } delete(al.ConnList, client.ID) al.Len-- case message := <-al.broadcast: log.Printf("Broadcast events: %s %s %d \n", message.ID, message.Content, message.Type) for id := range al.ConnList { if id != message.ID { err := al.sendMessage(id, message) if err != nil { log.Println("broadcastError: ", err) } } } case sign := <-al.cancel: log.Println("Termination event: ", sign) os.Exit(0) } } }
Because there are many types of messages, and the simple string cannot meet the requirements, the commonly used json format is selected for delivery. At present, the messages are divided into:
const ( // SystemMessage system message SystemMessage = iota // BroadcastMessage broadcast message (normal message) BroadcastMessage // HeartBeatMessage HeartBeatMessage // ConnectedMessage Launch Notification ConnectedMessage // Disconnect edmessage offline notification DisconnectedMessage ) // Message body structure type Message struct { ID string Content string SentAt int64 Type int // < systemmessage and other types are here }
If you have free time, make more chat rooms and optimize the current event cycle logic
If you have more spare power, do a better client?