WebSocket - 关闭握手大猩猩

来自 WebSocket RFC 的片段:


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


我正在尝试使用带有以下代码的Gorilla 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(正常):woops


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


蝴蝶不菲
浏览 286回答 1
1回答

繁星点点滴滴

服务器使用以下代码响应关闭帧:    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 时间旋转。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go