简体   繁体   中英

Sending a Websocket message to a specific channel in Go (using 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),
}

What should I change from here?

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.

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 Hub s 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)
            }
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM