文档管理中心

如何定位WebSocket连接异常断开

问题现象

场景一:在建立WebSocket连接时失败。

场景二:WebSocket连接成功后,过段时间异常断开,并且断开时间相对固定。

场景三:WebSocket连接成功,但是在收发消息时异常断开,断开时间不固定。

背景知识

  • 心跳机制:WebSocket默认开启心跳检测,需要服务器对客户端发送的Ping帧回复Pong,否则客户端会自动断开连接,默认超时时间为30s,可参考使用WebSocket访问网络场景介绍的说明事项。
  • wireshark:一款强大的网络协议分析工具,用于捕获和分析网络数据包,帮助用户深入理解和调试网络通信问题。
  • lws callback事件:WebSocket连接基于libwebsockets开源库实现,在hilog日志中会打印底层连接的回调事件lws callback reason is [lws_callback_reasons],callback详情描述可参考libwebsockets官网User Callback介绍。

问题定位

  1. 开启on('open')on('close')on('error')监听事件,并在回调事件内打印日志,以提供报错信息。
  2. 确认连接断开的时间规律,分析hilog日志及网络数据包:
  • WebSocket在连接过程中断开,未正常建立连接,搜索Lws client connection error关键词,判断连接失败原因,比如:
    • Lws client connection error conn fail: 110中的110在网络通信中代表连接超时,需要检查网络连接是否正常、服务器地址是否可达等问题。
      01-17 17:08:34.585   44111-44643   C015B0/om.test...cket/NETSTACK  com.test....bsocket  I     [websocket_exec.cpp:466] lws callback reason is 1
      01-17 17:08:34.585   44111-44643   C015B0/om.test...cket/NETSTACK  com.test....bsocket  I     [websocket_exec.cpp:332] Lws client connection error conn fail: 110
      ...
      01-17 17:08:34.588   44111-44111   A03D00/om.test...bsocket/JSAPP  com.test....bsocket  E     Websocket Client on error, error:{"code":200,"data":"0"}
    • Lws client connection error Timed out waiting SSL表示SSL认证卡住,需要检查服务地址是ws还是wss,服务器证书是否有效、SSL\TLS协议是否一致等问题。
      01-17 16:55:05.609   35392-35392   C015B0/om.test...cket/NETSTACK  com.test....bsocket  I     [websocket_exec.cpp:723] ConnectCallback connect success
      ...
      01-17 16:55:20.650   35392-35878   C015B0/om.test...cket/NETSTACK  com.test....bsocket  I     [websocket_exec.cpp:466] lws callback reason is 1
      01-17 16:55:20.650   35392-35878   C015B0/om.test...cket/NETSTACK  com.test....bsocket  I     [websocket_exec.cpp:332] Lws client connection error Timed out waiting SSL
      01-17 16:55:20.655   35392-35392   A03D00/om.test...bsocket/JSAPP  com.test....bsocket  E     Websocket Client on error, error:{"code":200,"data":"0"}
  • WebSocket在连接成功后,固定时长断开。比如连接总是运行60s、30s后断开,检查客户端和服务器设置的心跳超时时间:
    • 客户端会自动启用心跳机制,默认30s发送Ping帧,当客户端收到服务端响应的Pong帧,维持连接。lws callback reason is 9代表客户端已接收到Pong帧数据包:
      01-17 15:33:35.384   49856-50626   C015B0/om.test...cket/NETSTACK  com.test....bsocket  I     [websocket_exec.cpp:555] PingInterval is 30,  PongTimeout is 30
      ...
      01-17 16:46:55.036   49856-30249   C015B0/om.test...cket/NETSTACK  com.test....bsocket  I     [websocket_exec.cpp:466] lws callback reason is 10
      01-17 16:46:55.084   49856-30249   C015B0/om.test...cket/NETSTACK  com.test....bsocket  I     [websocket_exec.cpp:466] lws callback reason is 9
      01-17 16:47:25.086   49856-30249   C015B0/om.test...cket/NETSTACK  com.test....bsocket  I     [websocket_exec.cpp:466] lws callback reason is 10
      01-17 16:47:25.135   49856-30249   C015B0/om.test...cket/NETSTACK  com.test....bsocket  I     [websocket_exec.cpp:466] lws callback reason is 9
    • 当网络抖动等原因,服务器未回复Pong帧导致心跳检测失败,客户端自动关闭连接,触发on('close')事件,回调的error message为The link is down。
      01-17 18:45:37.620   16507-51025   C015B0/om.test...cket/NETSTACK  com.test....bsocket  I     [websocket_exec.cpp:466] lws callback reason is 10
      01-17 18:46:07.619   16507-51025   C015B0/om.test...cket/NETSTACK  com.test....bsocket  I     [websocket_exec.cpp:466] lws callback reason is 75
      01-17 18:46:07.619   16507-51025   C015B0/om.test...cket/NETSTACK  com.test....bsocket  E     [websocket_exec.cpp:427] The link is down, onError
      01-17 18:46:07.622   16507-16507   A03D00/om.test...bsocket/JSAPP  com.test....bsocket  E     Websocket Client on error, error:{"code":200,"data":"0"}
      01-17 18:46:07.623   16507-16507   A03D00/om.test...bsocket/JSAPP  com.test....bsocket  I     Websocket Client on close, code is 0, reason is The link is down
  • WebSocket在连接成功后,随机断开。抓包分析TCP交互,在wireshark中使用ip.src == [服务器ip地址] || ip.dst == [服务器ip地址]过滤数据包,率先发送[FIN, ACK]数据包的为主动断开方。比如下图为101.201.**.**服务端主动断开连接,再结合业务日志分析具体的断开原因。

分析结论

WebSocket连接异常断开通常有多种原因,需要结合hilog日志及网络数据包分析断开原因。通常60s固定时长断开为客户端心跳机制主动断开,需要检查网络链路是否通畅及服务器是否回复Pong帧。

修改建议

  1. 如果服务器自行实现了心跳检测,不会回复Pong帧,可以将WebSocketRequestOptions的pingInterval参数置为0,关闭客户端默认的心跳检测。
  2. 如果是网络抖动导致的连接失败或随机断开,参考如何优化WebSocket长连接在弱网环境下的重连效率与心跳机制
搜索
请输入您想要搜索的关键词