在用 Golang 开发 WebSocket 客户端时,我遇到了因连接关闭不当而导致的重复错误信息。要解决这些问题,了解关闭 WebSocket 连接的正确方法至关重要,我将在本篇文章中与大家分享。
——作者:Sean Zheng
设置 WebSocket 客户端
首先,让我们定义 WebSocket 客户端的基本结构和设置:
定义客户端结构
const defaultWebSocketClientEndpoint = "wss://api.fugle.tw/marketdata/v1.0/stock/streaming"
type WebSocketClientOption struct {
Endpoint string `json:"endpoint"`
APIKey string `json:"apiKey"`
}
type WebSocketClient struct {
Conn *websocket.Conn
option WebSocketClientOption
}
WebSocket 客户端构造函数
func NewWebSocketClient(option WebSocketClientOption) (*WebSocketClient, error) {
if option.Endpoint == "" {
option.Endpoint = defaultWebSocketClientEndpoint
}
return &WebSocketClient{
Conn: nil,
option: option,
}, nil
}
建立和关闭连接
正确处理 WebSocket 连接需要了解突然关闭 TCP 连接与有序关闭 WebSocket 连接之间的区别。
连接到 WebSocket
func (client *WebSocketClient) Connect() error {
conn, resp, err := websocket.DefaultDialer.Dial(client.option.Endpoint, nil)
if err != nil {
return err
}
defer resp.Body.Close()
client.Conn = conn
return nil
}
正确的 WebSocket 关闭说明
Conn.Close() 与发送关闭消息的区别
1. Conn.Close() 方法:
- 该方法是 net.Conn 接口的一部分,用于直接关闭 TCP 连接。它会立即终止底层 TCP 连接,而不管任何正在进行的数据传输。
- 使用 Conn.Close()可能会导致对等程序接收到不完整的数据,因为它没有遵循 WebSocket 协议来结束连接。这可能会导致对端收到一个 TCP RST(重置)数据包,表明连接突然终止。
- 它通常用于出错或需要立即断开连接,而不考虑从容完成数据交换的情况。
2. 发送关闭消息
- 在 WebSocket 协议中,关闭消息是一种特殊的控制消息,用于表示端点希望关闭连接。这是一个有序、优雅的关闭过程,允许对等方发送相应的关闭消息作为回应。
- 发送关闭消息后,应用程序通常会继续接收数据,直到收到对等方的关闭消息。这样可确保双方都有机会完成任何待处理的数据交换,遵守 WebSockets 的正常终止流程。
- 这是正确断开 WebSocket 连接的推荐方法,因为它符合 WebSocket 协议,能确保数据完整性和连接的正确终止。
关闭功能实现
func (client *WebSocketClient) Close() error {
// 发送 WebSocket 关闭消息
Deadline := time.Now().Add(time.Minute)
err := client.Conn.WriteControl(
websocket.CloseMessage,
websocket.FormatCloseMessage( websocket.CloseNormalClosure, "" ),
Deadline,
)
if err != nil {
return err
}
// 设置读取下一条消息的截止时间
err = client.Conn.SetReadDeadline(time.Now().Add( 5 * time.Second ))
if err != nil {
return err
}
// 读取消息,直到确认关闭消息
for {
_, _, err = client.Conn.NextReader()
if websocket.IsCloseError(err, websocket.CloseNormalClosure) {
break
}
if err != nil {
break
}
}
// 关闭 TCP 连接
err = client.Conn.Close()
if err != nil {
return err
}
return nil
}
结论
通过遵守概述的技术,您可以确保干净利落地终止 WebSocket 连接,而不会出现任何残余错误。这将提高应用程序的稳定性,并通过保持干净高效的通信通道来增强整体用户体验。
版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。