英文:
GO Websocket send all clients a message
问题
这段代码运行正常(为了更好的阅读,我对其进行了缩写)。
当Client1
向服务器发送请求时,服务器会立即回应。但是,其他客户端无法看到响应消息。
所以我想让它更进一步:当一个客户端向服务器发送请求时,服务器将回应所有客户端,以便所有客户端都能看到消息。
我该如何做到这一点?有没有适合初学者的示例或教程?
提前感谢!
服务器代码:
import (
"github.com/gorilla/websocket"
)
func main() {
http.Handle("/server", websocket.Handler(echoHandler))
}
func echoHandler(ws *websocket.Conn) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
return
}
for {
messageType, p, err := conn.ReadMessage()
if err != nil {
return
}
print_binary(p) // 简单打印消息
err = conn.WriteMessage(messageType, p);
if err != nil {
return
}
}
}
英文:
Everything works fine with this code (shortened it for better reading).
When Client1
sends a request to the Server, the Server responses to him instantly. But, the other clients can not see the response message.
So I want to make it go further: When a client sends a request to the server, the server will response to all clients so that all clients can see the message.
How can I do that? Any examples or nice tutorials for beginners?
Thanks in advance!
Server:
import (
"github.com/gorilla/websocket"
)
func main() {
http.Handle("/server", websocket.Handler(echoHandler))
}
func echoHandler(ws *websocket.Conn) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
return
}
for {
messageType, p, err := conn.ReadMessage()
if err != nil {
return
}
print_binary(p) // simple print of the message
err = conn.WriteMessage(messageType, p);
if err != nil {
return
}
}
}
答案1
得分: 10
你需要使用连接池来向所有连接广播消息。
你可以使用这个作为教程/示例:http://gary.burd.info/go-websocket-chat
简化一下:
连接池是一组已注册的连接,可以查看hub.connections
:
type connection struct {
// WebSocket连接
ws *websocket.Conn
// 用于传输消息的缓冲通道
send chan []byte
// 连接所属的连接池
h *hub
}
type hub struct {
// 已注册的连接,即连接池
connections map[*connection]bool
...
}
要向所有客户端广播消息,我们可以按照以下方式遍历连接池:
case m := <-h.broadcast:
for c := range h.connections {
select {
case c.send <- m:
default:
delete(h.connections, c)
close(c.send)
}
}
}
在这个示例中,h.broadcast
是一个包含需要广播的消息的通道。
我们使用select
语句的default
部分来删除具有满的或被阻塞的发送通道的连接。参考:https://stackoverflow.com/questions/32693931/what-is-the-benefit-of-sending-to-a-channel-by-using-select-in-go
英文:
You have to use connection pool to broadcast messages to all connections.
You can use that as tutorial/sample http://gary.burd.info/go-websocket-chat
Simplifying:
Connection pool is a collection of registered connections. See hub.connections
:
type connection struct {
// The websocket connection.
ws *websocket.Conn
// Buffered channel of outbound messages.
send chan []byte
// The hub.
h *hub
}
type hub struct {
// Registered connections. That's a connection pool
connections map[*connection]bool
...
}
To broadcast message for all clients, we iterate over connection pool like this:
case m := <-h.broadcast:
for c := range h.connections {
select {
case c.send <- m:
default:
delete(h.connections, c)
close(c.send)
}
}
}
h.broadcast
in that example is a channel with messages we need to broadcast.
We use default
section of the select
statement to delete connections with full or blocked send channels. See https://stackoverflow.com/questions/32693931/what-is-the-benefit-of-sending-to-a-channel-by-using-select-in-go
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论