dsgdsf12312
dsgdsf12312
2019-09-04 07:54

将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 doupijin0397 2年前

    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)
                }
            }
        }
    
    点赞 评论 复制链接分享

相关推荐