在底层,Websocket 协议如何检测连接的状态?

aza*_*tar 3 networking tcp network-protocols websocket

我正在与一位工程师同事讨论 Websocket 开销,我们都不确定 Websocket 如何实际检测客户端连接的状态。

  1. 是否有定期向客户端/服务器发送“状态”数据包?
  2. 它与低级 API 中的pingpong有什么关系吗?
  3. 框架呢?
  4. Websocket如何检测客户端已断开连接?服务器?

我很惊讶我找不到这个答案,但这可能是我的错误。我发现这个答案解决了可扩展性,但这不是我在这里要问的。这个答案涉及实施,但没有达到我在这里追求的深度。

jfr*_*d00 5

webSocket 连接是使用 webSocket 协议的 TCP 连接。默认情况下,只有当底层 TCP 意识到连接已关闭并且 webSocket 层正在侦听连接上的关闭事件并以这种方式通知时,服务器或客户端才知道连接何时消失。

webSocket 协议本身不需要心跳包来定期测试连接是否仍在工作。TCP 套接字可能看起来仍然处于活动状态,但连接实际上可能不再有效。另一端可能已消失或在中间被中断,并且一个或两个端点可能在任何给定时间都不知道这一点。

Socket.io 构建在 webSocket 之上,使用 ping 和 pong 数据包实现心跳,定期测试连接,实际上会检测客户端的非正常连接,关闭套接字,然后自动重新连接。

是否有定期向客户端/服务器发送“状态”数据包?

默认情况下,常规 webSocket 连接不是这样。

它与低级 API 中的 ping 或 pong 有什么关系吗?

客户端或服务器是否想要自己发送 ping 或 pong 数据包来实现某种连接验证检测,取决于客户端或服务器。

框架呢?

webSocket 帧是通过 webSocket 发送数据的数据格式。他们与这个问题没有任何关系。

Websocket如何检测客户端已断开连接?服务器?

如上所述。除非客户端/服务器实现自己的 ping/pong 系统来检测连接何时出现问题,否则它们仅依靠 TCP 信令来了解连接何时被另一端关闭。WebSocket 连接可能无法正常工作,客户端或服务器在尝试发送之前并不知道。


当浏览器窗口/选项卡打开 webSocket 连接,然后窗口/选项卡重定向到新 URL 时,浏览器将关闭与该窗口/选项卡关联的所有资源,包括任何 webSocket 连接。如果此时客户端和服务器之间的链接正常,那么服务器将被告知底层 TCP 连接(以及 webSocket)已关闭。如果网络链接断开,然后用户将该窗口/选项卡移动到新的 URL,则服务器不一定知道该连接无法正常工作,而不依赖 ping/pong 类型信令定期测试连接。

如果浏览器崩溃,操作系统应关闭该进程打开的所有套接字。

如果计算机/操作系统崩溃,套接字可能不会正常关闭(尽管这可能在某种程度上依赖于操作系统,也可能依赖于崩溃)。

  • @toszter - TCP 本身不会知道连接已经死亡,直到它收到来自另一端的关闭数据包或直到它尝试发送数据并收到错误并且所有重试尝试都失败。需要某种类型的保持活动数据包和响应才能可靠地检测已死亡的连接。这就是为什么socket.io 实现了这样的功能。 (2认同)