我曾经这样做过:
...
ws, err := websocket.Dial(url, "", origin)
...
var buffer = make([]byte, 512)
var rs = make([]byte, 0, 512)
L:
for {
m, err := ws.Read(buffer)
if err != nil {
if err == io.EOF {
break L
}
fmt.Println(err.Error())
return
}
rs = append(rs, buffer[:m]...)
if m < 512 {
break L
}
}
这有一个错误:如果消息的长度恰好是 512 或 1024 或 2048... 循环永远不会中断;它将停留在 ws.Read()
并等待而不抛出 io.EOF
。
后来我观察到 ws.Len()
总是比消息的长度长 4。
我将代码重写为:
var buffer = make([]byte, 512)
var rs = make([]byte, 0, 512)
var sum = 0
L:
for {
m, err := ws.Read(buffer)
if err != nil {
if err == io.EOF {
break L
}
fmt.Println(err.Error())
return
}
rs = append(rs, buffer[:m]...)
sum+=m
if sum >= ws.Len()-4 {
break L
}
}
这样就可以了。
但是数字 4
是一个神奇的代码。
有没有办法找到消息的最大长度?
有 friend 建议分离消息包,但我认为WebSocket不应该考虑卡包或分离。
WebSocket 客户端读取消息最合适的方式是什么?
最佳答案
看起来您正在使用 golang.org/x/net/websocket 包。使用该包的 Read 方法无法可靠地检测消息边界。
要修复,请使用 websocket.Message阅读消息。
var msg string
err := websocket.Message.Receive(ws, &msg)
if err != nil {
// handle error
}
// msg is the message
请注意 golang.org/x/net/websocket documentation说:
This package currently lacks some features found in an alternative and more actively maintained WebSocket package:
gorilla documentation和 examples显示如何阅读消息。
关于go - WebSocket 客户端如何知道消息已被完整读取?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54997127/