如果我没有在任何地方阅读消息,则不会为 gorilla/websocket 调用 CloseHandler,最终我只会收到写入错误

CloseHandler is not called for a gorilla/websocket if I am not reading messages anywhere, I simply get a write error eventually

我有一个使用 gorilla/websocket 的 websocket 服务器。

我有一种情况,我只是将消息写入一组 websockets。当我在浏览器端关闭 websocket 时,我的自定义 CloseHandler 永远不会被调用。

但是,添加无限期调用 ReadMessage 的 goroutine(直到出现某些错误)会导致调用 CloseHandler。

基本思路如下: 在一个 goroutine 中,我 运行 是这样的:

for {
    for client := range clients {
        client.stream <- data
    }
    time.Sleep(time.Second)
}

和其他代码,在单独的 goroutine 中调用,每个客户端一个:

go (func() {
    // If I call wsock.ReadMessage here, my CloseHandler works!
})()

for msg := range myclient.stream {
    if err := wsock.WriteMessage(websocket.TextMessage, msg); err != nil {
        break
    }
}

当我在浏览器端关闭 websocket 时,我希望 CloseHandler 被调用,但是,它从未被调用,相反,我最终在 WriteMessage 调用中遇到错误。

close message is received from the peer. The application must read the connection to receive close and other control messages.

时调用关闭处理程序

如果应用程序不读取连接或对等方不发送关闭消息,则不会调用关闭处理程序。

如果您的目标是检测关闭的连接,则读取连接直到返回错误,如 the documentation 所示:

func readLoop(c *websocket.Conn) {
    for {
        if _, _, err := c.NextReader(); err != nil {
            c.Close()
            break
        }
    }
 }

只有当应用程序必须在连接将关闭消息弹回对等点之前执行某些操作时,应用程序才应设置关闭处理程序。