将 Websocket 消息发送到 Go 中的特定通道(使用 Gorilla)

Sending a Websocket message to a specific channel in Go (using Gorilla)

我是 Go 的新手,发现自己将使用套接字作为我的第一个项目。这是一个多余的问题,但我未能理解如何将 websocket 更新发送到 Go 中的特定通道(使用 Gorilla)。

我正在使用code sample from this link

这个方法。但是修改发送消息到特定频道失败。

这是我的示例代码 main.go

func main() {
    flag.Parse()
    hub := newHub()
    go hub.run()
    http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
        fmt.Println(hub)
        serveWs(hub, w, r)
    })
    err := http.ListenAndServe(*addr, nil)
    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}

还有另外两个文件 hub.go 和 client.go 我认为 hub.go 下面可以做点什么

return &Hub{
    broadcast:  make(chan []byte),
    register:   make(chan *Client),
    unregister: make(chan *Client),
    clients:    make(map[*Client]bool),
}

我应该从这里更改什么?

更新

我想做的是我有一个用 go 编写的套接字服务器。 现在假设我们有许多用 react 编写的客户端在服务器上监听特定的 url,比如 wss://abc.com/wss1 或者可能是 wss://abc.com/wss2

现在,如果客户端 wss1 向服务器发送消息,服务器将向所有侦听 url wss1 而不是 wss2 的客户端发出此消息,反之亦然。

到目前为止,我已经能够向所有客户端广播,无论是 wss1 还是 wss2。 希望我说清楚了。

要向 Gorilla 聊天示例添加 "channel" 或 "chat room" 功能,请执行以下操作。我将在此答案中使用 "room" 一词,以避免与 Go 频道混淆。

定义包含负载和房间标识符的消息类型:

type message struct {
   roomID string
   data []byte
}

将中心广播频道替换为:

broadcast chan message

为客户类型添加房间标识符:

type Client struct {
    roomID string
    hub *Hub
    ...
}

处理程序从 request URI 中提取房间标识符,并在创建 Client 和发送 message 时设置房间标识符。

Hubs clients 字段更改为由房间标识符键入的地图。初始化集线器时适当初始化此字段。

// Registered clients by room
rooms map[string]map[*Client]bool

更改 Hub run 函数以处理房间。此代码在结构上类似于原始示例中的代码。

    select {
    case client := <-h.register:
        room := h.rooms[client.roomID]
        if room == nil {
           // First client in the room, create a new one
           room = make(map[*Client]bool)
           h.rooms[client.roomID] = room
        }
        room[client] = true
    case client := <-h.unregister:
        room := h.rooms[client.roomID]
        if room != nil {
            if _, ok := room[client]; ok {
                delete(room, client)
                close(client.send)
                if len(room) == 0 {
                   // This was last client in the room, delete the room
                   delete(h.rooms, client.roomID)
                }
            }
         }
    case message := <-h.broadcast:
        room := h.rooms[message.roomID]
        if room != nil {
            for client := range room {
                select {
                case client.send <- message.data:
                default:
                    close(client.send)
                    delete(room, client)
                }
            }
            if len(room) == 0 {
                // The room was emptied while broadcasting to the room.  Delete the room.
                delete(h.rooms, message.roomID)
            }
        }
    }