我曾经这样做过:
...
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
是一个神奇的密码。
是否可以找到邮件的最大长度?
一些朋友建议分离消息包,但我认为WebSocket不应该考虑消息卡住或分离。
WebSocket客户端读取消息的最正确方法是什么?
答案 0 :(得分:1)
您似乎正在使用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表示:
此程序包当前缺少在替代性的且维护程度更高的WebSocket程序包中发现的一些功能:
大猩猩documentation和examples展示了如何阅读消息。