问题: WebSocket重连问题
摘要:
在经历网络波动
或其他连接问题后,应用程序无法重新连接到WebSocket服务器。此外,心跳机制未能有效处理丢失的ping并重试。
复现步骤:
- 启动应用程序并建立WebSocket连接。
- 引入网络中断(例如,断开并重新连接网络)。
- 观察应用程序在尝试重新连接WebSocket服务器时的行为。
- 监控心跳机制,查看是否正确处理了丢失的ping。
预期行为:
- 在连接丢失后以及读取消息错误后,应用程序应自动尝试重新处理或重新连接到WebSocket服务器。
- 心跳机制应正确检测到丢失的pong并触发重连尝试。
实际行为:
- 在网络中断后,应用程序未能重新连接到WebSocket服务器。
- 心跳机制sned ping,而未能成功处理丢失的pong并启动重连。
相关代码片段:
func (s *State) WsConnect() error {
wsConn := s.Conn
wsUrl := wsConn.Url
if s.SessionId != "" {
wsUrl = fmt.Sprintf("%s&sn=%d&session_id=%s&resume=1", wsUrl, s.MaxSN, s.SessionId)
}
log.Infof("connect to gateway: %s", wsUrl)
conn, resp, err := websocket.DefaultDialer.Dial(wsUrl, nil)
log.Infof("connect to gateway resp: %+v", resp)
if err != nil {
log.Panicf("connect to ws server failed, %e", err)
}
// set ws conn
s.Conn.WebConn = conn
s.wsConnectSuccess()
go func() {
defer func() {
conn.Close()
}()
for {
_, msg, err := conn.ReadMessage()
if err != nil {
log.Errorf("read msg error: %e", err)
break
}
log.WithField("msg", msg).Trace("websocket data receive")
s.ReceiveData(msg)
}
}()
return nil
}
环境:
- 操作系统: Macos 14.4.1 (23E224)
- Go 版本: go1.22.5 darwin/arm64
- 应用程序版本: 1.3.1
- 网络连接方式: WIFI
日志:
网络切换之后 send Ping 卡住,即没有pong!也没有再次重连或者send Ping!
INFO[2024-07-15 04:45:43] send Ping ping="{\"s\":2,\"sn\":10,\"d\":null}"
INFO[2024-07-15 04:45:43] pong!
INFO[2024-07-15 04:46:13] send Ping ping="{\"s\":2,\"sn\":10,\"d\":null}"
ERRO[2024-07-15 04:46:13] read msg error: &{%!e(string=read) %!e(string=tcp) %!e(*net.TCPAddr=&{[198 18 0 1] 60851 }) %!e(*net.TCPAddr=&{[198 18 20 226] 443 }) %!e(*os.SyscallError=&{read 54})}
ERRO[2024-07-15 04:46:19] heart beat time out, try reconnect!
INFO[2024-07-15 04:46:19] retry by event:&{0xc000528b00 heartbeatTimeout connected retry <nil> [] false false 0x1de58c0}
INFO[2024-07-15 04:46:19] now session state is: retry
INFO[2024-07-15 04:46:19] retry heart beat...
INFO[2024-07-15 04:46:19] send Ping ping="{\"s\":2,\"sn\":10,\"d\":null}"
INFO[2024-07-15 04:46:19] try 0 times call function %!s(func() error=0x23910a0) error="retry next ping action"
INFO[2024-07-15 04:46:23] retry heart beat...
INFO[2024-07-15 04:46:23] send Ping ping="{\"s\":2,\"sn\":10,\"d\":null}"
INFO[2024-07-15 04:46:23] try 1 times call function %!s(func() error=0x23910a0) error="retry next ping action"
INFO[2024-07-15 04:46:23] send Ping ping="{\"s\":2,\"sn\":10,\"d\":null}"
未知原因
INFO[2024-07-15 04:54:01] send Ping ping="{\"s\":2,\"sn\":15,\"d\":null}"
INFO[2024-07-15 04:54:01] pong!
INFO[2024-07-15 04:54:31] send Ping ping="{\"s\":2,\"sn\":15,\"d\":null}"
INFO[2024-07-15 04:54:31] pong!
ERRO[2024-07-15 04:54:49] read msg error: &{%!e(int=1006) %!e(string=unexpected EOF)}
INFO[2024-07-15 04:55:01] send Ping ping="{\"s\":2,\"sn\":15,\"d\":null}"
INFO[2024-07-15 04:55:31] send Ping ping="{\"s\":2,\"sn\":15,\"d\":null}"
INFO[2024-07-15 04:56:01] send Ping ping="{\"s\":2,\"sn\":15,\"d\":null}"
INFO[2024-07-15 04:56:31] send Ping ping="{\"s\":2,\"sn\":15,\"d\":null}"
INFO[2024-07-15 04:57:01] send Ping ping="{\"s\":2,\"sn\":15,\"d\":null}"
INFO[2024-07-15 04:57:31] send Ping ping="{\"s\":2,\"sn\":15,\"d\":null}"
INFO[2024-07-15 04:58:01] send Ping ping="{\"s\":2,\"sn\":15,\"d\":null}"
INFO[2024-07-15 04:58:31] send Ping ping="{\"s\":2,\"sn\":15,\"d\":null}"
INFO[2024-07-15 04:59:01] send Ping ping="{\"s\":2,\"sn\":15,\"d\":null}"
INFO[2024-07-15 04:59:31] send Ping ping="{\"s\":2,\"sn\":15,\"d\":null}"
INFO[2024-07-15 05:00:01] send Ping ping="{\"s\":2,\"sn\":15,\"d\":null}"
INFO[2024-07-15 05:00:31] send Ping ping="{\"s\":2,\"sn\":15,\"d\":null}"
INFO[2024-07-15 05:01:01] send Ping ping="{\"s\":2,\"sn\":15,\"d\":null}"
INFO[2024-07-15 05:01:31] send Ping ping="{\"s\":2,\"sn\":15,\"d\":null}"