In the example directory of Gorilla websocket there is a file called hub.go.
https://github.com/gorilla/websocket/blob/master/examples/chat/hub.go
Here you can find a method on the type hub that does this.
func (h *hub) run() {
for {
select {
case c := <-h.register:
h.connections[c] = true
case c := <-h.unregister:
if _, ok := h.connections[c]; ok {
delete(h.connections, c)
close(c.send)
}
case m := <-h.broadcast:
for c := range h.connections {
select {
case c.send <- m:
default:
close(c.send)
delete(h.connections, c)
}
}
}
}
}
Why does it not just send to the c.send channel straight up in the last case like this?
case m := <-h.broadcast:
for c := range h.connections {
c.send <- m
}
https://gobyexample.com/non-blocking-channel-operations
And to be more clear: for a non-blocking "send", the first
case
will happen if there is a receiver already waiting for a message. Else it falls back todefault
It's method of guaranted nonblocking send to channel. In case of c.send chan can't accept new messages now, a default branch will be executed. Without select{} block sending to unbuffered or fully filled buffered channel can be blocked.