紫气旋面双凤阁 青松还有万年枝
目录
出问题的代码
在执行消息读取时出错,报了websocket: close 1005 (no status)错误
原因分析
打开页面窗口时,前端需要和我建立websocket连接,页面如果点击关闭时前端一方关掉连接,而此时你的消息读取逻辑 webconn.ReadMessage() 这一句如果还继续执行,那么就会报这个错。
如上面我的代码,不论在报什么错时都continue,这是不行的。
解决办法
你可能已经想到解决办法了:关闭时停止读取
遇到报错直接打印错误并return即可。或者像下面这样处理:
当然,目前能确认的是,前端关闭连接时会报这个错,也就是说在报这个错时进行特殊判断,进行return,否则打印其他类型的报错信息:
messageType, userBytes, err := webconn.ReadMessage()
if err != nil {
if !strings.Contains(err.Error(), "websocket: close 1005") {
logrus.Error("failed to get data from web:", err.Error())
}
logrus.Info("ws conn is closed.")
webconn.Close()
conn.Close()
return
}
相关源码
另外,附上源码:
// Close codes defined in RFC 6455, section 11.7.
const (
CloseNormalClosure = 1000
CloseGoingAway = 1001
CloseProtocolError = 1002
CloseUnsupportedData = 1003
CloseNoStatusReceived = 1005
CloseAbnormalClosure = 1006
CloseInvalidFramePayloadData = 1007
ClosePolicyViolation = 1008
CloseMessageTooBig = 1009
CloseMandatoryExtension = 1010
CloseInternalServerErr = 1011
CloseServiceRestart = 1012
CloseTryAgainLater = 1013
CloseTLSHandshake = 1015
)
func (e *CloseError) Error() string {
s := []byte("websocket: close ")
s = strconv.AppendInt(s, int64(e.Code), 10)
switch e.Code {
case CloseNormalClosure:
s = append(s, " (normal)"...)
case CloseGoingAway:
s = append(s, " (going away)"...)
case CloseProtocolError:
s = append(s, " (protocol error)"...)
case CloseUnsupportedData:
s = append(s, " (unsupported data)"...)
case CloseNoStatusReceived:
s = append(s, " (no status)"...)
case CloseAbnormalClosure:
s = append(s, " (abnormal closure)"...)
case CloseInvalidFramePayloadData:
s = append(s, " (invalid payload data)"...)
case ClosePolicyViolation:
s = append(s, " (policy violation)"...)
case CloseMessageTooBig:
s = append(s, " (message too big)"...)
case CloseMandatoryExtension:
s = append(s, " (mandatory extension missing)"...)
case CloseInternalServerErr:
s = append(s, " (internal server error)"...)
case CloseTLSHandshake:
s = append(s, " (TLS handshake error)"...)
}
if e.Text != "" {
s = append(s, ": "...)
s = append(s, e.Text...)
}
return string(s)
}