1
我試圖修改大猩猩聊天示例以發送消息到特定的客戶端而不是廣播。首先,我將特定客戶端存儲在集線器中,以防止它是Id。Websocket發送到特定的客戶端,而不是廣播
Hub.go
type Hub struct {
Clients map[int]*Client // Changed this piece to store id (int)
Broadcast chan []byte
Register chan *Client
Unregister chan *Client
}
func (h *Hub) Run() {
for {
select {
case client := <-h.Register:
fmt.Println("hub client register")
h.Clients[client.Id] = client
case client := <-h.Unregister:
fmt.Println("hub client Unregister")
fmt.Println(h.Clients[client.Id])
if h.Clients[client.Id] != nil {
delete(h.Clients, client.Id)
close(client.Send)
}
case message := <-h.Broadcast:
fmt.Println("to send to a specific client", string(message))
}
}
}
客戶
我添加一個字段ID INT給客戶知道哪些客戶端發送一個消息
type Client struct {
Hub *Hub
Conn *websocket.Conn
Send chan []byte
Id int // Id of the client,
}
func (c *Client) readPump() {
defer func() {
c.Hub.Unregister <- c
c.Conn.Close()
}()
c.Conn.SetReadLimit(maxMessageSize)
c.Conn.SetReadDeadline(time.Now().Add(pongWait))
c.Conn.SetPongHandler(func(string) error { c.Conn.SetReadDeadline(time.Now().Add(pongWait)); return nil })
for {
_, message, err := c.Conn.ReadMessage()
if err != nil {
if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway) {
log.Printf("error: %v", err)
}
break
}
message = bytes.TrimSpace(bytes.Replace(message, newline, space, -1))
fmt.Println("client read message", string(message), "from", c.Id)
// {"to":512,"message":"Hi there."}
c.Hub.Broadcast <- message
}
}
是什麼接下來要發送消息到特定的客戶端而不是廣播。
消息本身即將來自客戶端的JSON,指定'to'指示要發送的對象以及要發送的消息。
{"to":512,"message":"Hi there."}
謝謝。我們是否需要違約條款?我在中心做了同樣的事情,但未註冊的處理程序。請指教。 – Developer
如果您不添加默認子句,那麼集線器可以阻止死客戶端。原始示例中的客戶端發送通道的容量大於1(我忘記了確切的值)。如果通道填滿容量,那麼客戶端的發送循環可能會停留在對對等體的寫入中。最好放下客戶端然後停止集線器。 –