WebSocket - 关闭握手大猩猩



来自WebSocket RFC的代码片段:

要使用状态代码(第 7.4 节(/code/和可选的关闭原因(第 7.1.6 节(/reason/启动 WebSocket 关闭握手,端点必须发送关闭控制帧,如第 5.5.1 节中所述,其状态代码设置为/code/且关闭原因设置为/reason/。 端点发送和接收关闭控制帧后,该端点应关闭 WebSocket 连接,如第 7.1.1 节中所定义。

我正在尝试使用以下代码使用大猩猩 WebSocket 包进行关闭握手:

服务器:

// Create upgrader function
conn, err := upgrader.Upgrade(w, r, nil)
// If there is an error stop everything.
if err != nil {
    fmt.Println(err)
    return
}
for {
    // Read Messages
    _, _, err := conn.ReadMessage()
    // Client is programmed to send a close frame immediately...
    // When reading close frame resend close frame with same
    // reason and code
    conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(1000, "woops"))
    fmt.Println(err)
    break
}

客户:

d := &websocket.Dialer{}
conn, _, err := d.Dial("ws://localhost:8080", nil)
if err != nil {
    fmt.Println(err)
    return
}
go func() {
    for {
        // Read Messages
        _, _, err := conn.ReadMessage()
        if c, k := err.(*websocket.CloseError); k {
            if(c.Code == 1000) {
                // Never entering since c.Code == 1005
                fmt.Println(err)
                break
            }
        }
    }
}()
conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(1000, "woops"))
for {}

服务器正在按预期读取关闭帧,输出以下内容:

WebSocket:关闭 1000(正常(:呜呜

但是,客户端就像在发送关闭消息后停止阅读一样。ReadMessage继续返回错误 1005。我做错了什么?

服务器使用

代码响应关闭帧:

    c.WriteControl(CloseMessage, []byte{}, time.Now().Add(writeWait))

这被转换为客户端的关闭代码 1005(未收到状态(。

客户端应用程序看不到服务器写入的 1000 oops 关闭帧,因为 websocket 连接在收到第一个关闭帧后停止从网络读取。

客户端应用程序应在从 ReadMessage 返回错误时退出循环。无需检查特定的关闭代码。

for {
    // Read Messages
    _, _, err := conn.ReadMessage()
    if err != nil {
        break
    }
}

与问题中的问题无关,服务器应用程序应在发送关闭帧后关闭 websocket 连接。

同样与问题中的问题无关,使用 select {} 而不是 for {} 来阻止主 goroutine。前者只是阻止了goroutine。 后者使用 CPU 时间旋转。

相关内容

  • 没有找到相关文章

最新更新