我是Go的新手,并且发现自己作为第一个项目使用套接字。这是一个多余的问题,但是我无法理解如何将Websocket更新发送到Go中的特定客户端(使用Gorilla)。
我要解决的主要问题是-使用websocket和搜索引擎(如ES / Lucene)建立预输入。我在搜索引擎上维护了一堆索引,并在其周围进行了Go包装。当我开始在Go中使用websockets时,几乎发现了所有展示广播机制的示例。当我尝试对此进行深入研究并尝试根据此线程和此答案中给出的示例修改Gorilla的github存储库中给出的示例时,我似乎不太明白,以及它如何适合connections``client.go
connections``client.go
理想情况下,我希望看到此工作的方式是-
服务器如何唯一标识Client?
Client
我已经使用了大猩猩的Github 回购中给出的示例
从我的代码库中hub.go有以下内容
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
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 }
请注意-我将Id在Client结构中添加一个字段。我怎样才能从这里开始?
Id
聊天示例显示了如何实现广播。如果不需要广播,则聊天示例不是应用程序的理想起点。
要将消息发送到特定的websocket连接,只需使用NextWriter或WriteMessage写入该连接。这些方法不支持并发编写器,因此您可能需要使用互斥量或goroutine来确保使用单个编写器。
查找特定*websocket.Connection内容的简单方法是将其传递*websocket.Connection给需要它的代码。如果应用程序需要将其他状态与连接相关联,则定义一个类型以保留该状态并向其传递指针:
*websocket.Connection
type Client struct { conn *websocket.Conn mu sync.Mutex ... }
该Hub可以进行修改,以将消息发送到特定的连接,但如果不需要广播这是一个迂回路径。方法如下:
Hub
将ID字段添加到客户端:
ID idType // replace idType with int, string, or whatever you want to use
将Gorilla中心字段从更改connections map[*connection]bool为connections map[idType]*connection。
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) } } }
通过创建message具有适当ID的将邮件发送到特定客户端:
message
hub.send <- message{ID: targetID, data: data}