【发布时间】:2020-04-08 19:29:36
【问题描述】:
我正在尝试用 gorilla/websocket 编写一个简单的 go websocket 服务器
http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
if os.Getenv("env") == "development" {
upgrader.CheckOrigin = func(r *http.Request) bool { return true }
}
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Printf("Websocket error: %s", err)
return
}
defer conn.Close()
// Register client
clients[conn] = true
for {
message := message.Message{}
_, msg, err := conn.ReadMessage()
if err != nil {
log.Printf("Websocket error: %s", err)
return
}
res, _ = json.Marshal(context.Game)
// Send to every client that is currently connected
for client := range clients {
err := client.WriteMessage(websocket.TextMessage, res)
if err != nil {
// Remove connection
client.Close()
delete(clients, client)
}
}
}
})
_, msg, err := conn.ReadMessage() 行抛出错误并关闭 websocket,但我不知道为什么。
错误是close 1006 (abnormal closure): unexpected EOF。我怎样才能防止这种情况发生?
【问题讨论】:
-
听起来像是客户端的东西。虽然我猜这可能与
clients上的竞争条件有关。 -
该错误表示对端关闭了连接而没有发送关闭消息。 RFC 将此称为“异常关闭”,但接收到的错误是正常的。忽略错误。如前一条评论所述,
clients存在数据竞赛。 -
@CeriseLimón 忽略该特定错误的最佳方法是什么?或者我想更好地追踪比赛条件?
-
@peter176 使用UnexpectedCloseError。预计会出现其他错误,例如 websocket.CloseGoingAway。应用程序同时读取和写入
clients。这与错误无关,但您应该修复它。 -
@peter176 看看Gorilla Chat Example。该示例展示了如何使用 UnexpectedCloseError 以及如何在没有数据竞争的情况下维护连接映射。