Go WebSocket错误:关闭1006(异常关闭):意外EOF

ilmyapht  于 2023-04-27  发布在  Go
关注(0)|答案(2)|浏览(1081)

我正在尝试用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。如何防止此错误?

gwbalxhn

gwbalxhn1#

该错误表示对等方在没有发送关闭消息的情况下关闭了连接。RFC将此称为“异常关闭”,但接收到该错误是正常的。
使用IsUnexpectedCloseError过滤掉预期的关闭错误。Gorilla Chat Example展示了如何使用该函数(在此处查看代码)。
正如Adrian指出的那样,问题中的应用程序在clients上存在数据竞争。Gorilla Chat示例展示了如何在没有数据竞争(中心)的情况下维护客户端Map。

l0oc07j2

l0oc07j22#

除了服务器和客户端本身断开连接外,您可能还需要注意WS是否由于中间代理转发的存在而断开连接。
例如,使用nginx反向代理后,连接到sokcet后一段时间后报告错误,这是由不适当的超时设置引起的。
例如

location /wss {
        proxy_pass http://127.0.0.1:9091/ws;
        proxy_http_version 1.1;
        proxy_connect_timeout 4s;
        proxy_read_timeout 120s;
        proxy_send_timeout 12s;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header X-Real-IP $remote_addr;
    }

proxy_read_timeout time设置为大于服务器的心跳时间可以解决此断开问题

相关问题