dsgdsf12312 2019-09-04 07:54
浏览 259
已采纳

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

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 how to send a websocket update to a specific channel in Go (using Gorilla).

I am using code sample from this link

this method. But failed to modify to send messages to specific channel.

Here is my sample code 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)
}

}

There is other two files called hub.go and client.go I think hub.go below here something could be done

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

Please suggest what should I change from here? Thanks in advanced.

****UPDATE**

What I am trying to do is I have a socket server written in go. Now suppose we have many clients written in react listening on server with a specific url like wss://abc.com/wss1 or may be wss://abc.com/wss2

Now if client wss1 send a message to server, server will emit this message all clients listening on url wss1 not wss2 and vice versa.

Till now i have been able to do broadcast to all clients irrespective of wss1 or wss2. Hope I made it clear.

  • 写回答

1条回答 默认 最新

  • doupijin0397 2019-09-05 17:31
    关注

    To add a "channel" or "chat room" feature to the Gorilla chat example, do the following. I'll use the word "room" in this answer to avoid confusion with Go channels.

    Define a type for messages that includes the payload and a room identifier:

    type message struct {
       roomID string
       data []byte
    }
    

    Replace the hub broadcast channel with:

    broadcast chan message
    

    Add a room identifier to the Client type:

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

    The handler extracts the room identifier from the request URI and sets the room identifier when creating a Client and sending a message.

    Change the Hubs clients fields to a map keyed by room identifier. Initialize this field as appropriate when initializing the hub.

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

    Change the Hub run function to work with rooms. This code is structurally similar to the code in the original example.

        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)
                }
            }
        }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误
  • ¥15 一道python难题3
  • ¥15 牛顿斯科特系数表表示
  • ¥15 arduino 步进电机
  • ¥20 程序进入HardFault_Handler
  • ¥15 oracle集群安装出bug
  • ¥15 关于#python#的问题:自动化测试