在我的代码库中hub.go具有以下type Hub struct { // Registered clients. clients map[*Client]bool // Inbound messages from the clients. broadcast chan []byte // Register requests from the clients. register chan *Client // Unregister requests from clients. unregister chan *Client connections map[string]*connection}func newHub() *Hub { return &Hub{ broadcast: make(chan []byte), register: make(chan *Client), unregister: make(chan *Client), clients: make(map[*Client]bool), connection: make(map[*Client]bool), // is this alright? }}func (h *Hub) run() { for { select { case client := <-h.register: h.clients[client] = true case client := <-h.unregister: if _, ok := h.clients[client]; ok { delete(h.clients, client) close(client.send) } case message := <-h.broadcast: for client := range h.connections { select { case client.send <- message: default: close(client.send) delete(h.connections, client) } } } }},我不确定应该添加到client.go 中的内容type Client struct { // unique ID for each client // id string // Hub object hub *Hub // The websocket connection. conn *websocket.Conn // Buffered channel of outbound messages. send chan []byte // connection --> (what should the connection property be?) connection string}请注意-我将在Client结构中添加一个Id字段.我怎样才能从这里开始?解决方案聊天示例显示了如何实现广播.如果不需要广播,则聊天示例不是应用程序的理想起点.要将消息发送到特定的websocket连接,只需使用 NextWriter 或 WriteMessage .这些方法不支持并发编写器,因此您可能需要使用互斥量或goroutine来确保单个编写器.查找特定*websocket.Connection的简单方法是将*websocket.Connection传递给需要它的代码.如果应用程序需要将其他状态与连接相关联,则定义一个类型以保留该状态并在其周围传递一个指针:type Client struct { conn *websocket.Conn mu sync.Mutex ...}可以修改Hub以将消息发送到特定的连接,但是如果不需要广播,则为回旋路径.操作方法如下:将ID字段添加到客户端: ID idType // replace idType with int, string, or whatever you want to use将Gorilla中心字段从connections map[*connection]bool更改为connections map[idType]*connection.定义包含消息数据和目标客户端ID的消息类型:type message struct { ID idtype data []byte}将中心广播字段替换为: send chan message将循环中心更改为:for { select { case client := <-h.register: h.clients[client.ID] = client case client := <-h.unregister: if _, ok := h.clients[client.ID]; ok { delete(h.clients, client.ID) close(client.send) } case message := <-h.send: if client, ok := h.clients[message.ID]; ok { select { case client.send <- message.data: default: close(client.send) delete(h.connections, client) } } }通过创建具有适当ID的message将消息发送到特定客户端: hub.send <- message{ID: targetID, data: data}I am very new to Go and have found myself working with sockets as my first project. This is a redundant question, but I have failed to understand howto send a websocket update to a specific client in Go (using Gorilla).The broad problem that I am trying to solve is - Building a typeahead using websockets and a search engine like ES/Lucene. I have maintained a bunch of indexes on my search engine and have a Go wrapper around it. When I started working on using websockets in Go, I have been finding almost all the examples showing broadcasting mechanism. When I tried to dig into this and tried to modify the example given in Gorilla's github repo based on the examples given in this thread and in this answer, I don't seem to understand connections and how does that fit in client.goIdeally, the way I would like to see this working is -A socket connection between the client and server is establishedUpon the client sending inputs via the socket, the server fetches it and throws into into a channel (Go channel)The indexing wrapper checks for this channel, and once there is something to fetch, the index is retrieved and written back to the socketHow can the server uniquely identify the Client?I have used the examples given on Gorilla's Github repoFrom my codebase hub.go has the following type Hub struct { // Registered clients. clients map[*Client]bool // Inbound messages from the clients. broadcast chan []byte // Register requests from the clients. register chan *Client // Unregister requests from clients. unregister chan *Client connections map[string]*connection}func newHub() *Hub { return &Hub{ broadcast: make(chan []byte), register: make(chan *Client), unregister: make(chan *Client), clients: make(map[*Client]bool), connection: make(map[*Client]bool), // is this alright? }}func (h *Hub) run() { for { select { case client := <-h.register: h.clients[client] = true case client := <-h.unregister: if _, ok := h.clients[client]; ok { delete(h.clients, client) close(client.send) } case message := <-h.broadcast: for client := range h.connections { select { case client.send <- message: default: close(client.send) delete(h.connections, client) } } } }}and I am unsure with what I should be adding to client.gotype Client struct { // unique ID for each client // id string // Hub object hub *Hub // The websocket connection. conn *websocket.Conn // Buffered channel of outbound messages. send chan []byte // connection --> (what should the connection property be?) connection string}Please note - I will be adding an Id field within the Client struct. How can I proceed from here? 解决方案 The chat example shows how to implement broadcast. The chat example is not a good starting point for an application if broadcast is not required.To send a message to a specific websocket connection, simply write to the connection using NextWriter or WriteMessage. These methods do not support concurrent writers, so you may need to use a mutex or goroutine to ensure a single writer.The simple approach for finding a specific *websocket.Connection is to pass *websocket.Connection to the code that needs it. If the application needs to associate other state with a connection, then define a type to hold that state and pass a pointer to that around:type Client struct { conn *websocket.Conn mu sync.Mutex ...}The Hub can be modified to send messages to specific connection, but it's a roundabout path if broadcast is not needed. Here's how to do it:Add ID field to client: ID idType // replace idType with int, string, or whatever you want to useChange the Gorilla hub field from connections map[*connection]bool to connections map[idType]*connection.Define a message type containing the message data and the ID of the target client:type message struct { ID idtype data []byte}Replace the hub broadcast field with: send chan messageChange the hub for loop to:for { select { case client := <-h.register: h.clients[client.ID] = client case client := <-h.unregister: if _, ok := h.clients[client.ID]; ok { delete(h.clients, client.ID) close(client.send) } case message := <-h.send: if client, ok := h.clients[message.ID]; ok { select { case client.send <- message.data: default: close(client.send) delete(h.connections, client) } } }Send messages to a specific client by creating a message with the appropriate ID: hub.send <- message{ID: targetID, data: data} 这篇关于将Websocket消息发送到Go中的特定客户端(使用Gorilla)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
08-20 07:48
查看更多