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

At a low level, how does the Websocket protocol detect the status of a connection?

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

  1. 是否有 "status" 数据包定期发送到 client/server?
  2. ping or pong低级别API有关系吗?
  3. frames呢?
  4. Websocket如何检测客户端断开连接?服务器?

我很惊讶我在 SO 上找不到这个答案,但这可能是我的错误。我发现 this answer addresses scalability, but that's not what I'm asking here. 涉及实现,但不是我在这里追求的深度。

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

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

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

Is there a "status" packet sent to the client/server periodically?

常规 webSocket 连接默认情况下不存在。

Does it have anything to do with ping or pong in the low level API?

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

What about frames?

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

How does the Websocket detect that it's disconnected on the client? the server?

如上所述。除非 client/server 实施他们自己的 ping/pong 系统来检测连接何时出错,否则他们仅依靠 TCP 信号来了解连接何时被另一端关闭。在客户端或服务器尝试发送之前,webSocket 连接可能无法正常工作。


当浏览器 window/tab 打开一个 webSocket 连接然后 window/tab 被重定向到一个新的 URL 时,浏览器将关闭与该 window/tab 关联的所有资源包括任何 webSocket 连接。如果此时客户端和服务器之间的 link 正常运行,则服务器将被告知底层 TCP 连接(以及 webSocket)已关闭。如果网络 link 出现故障,然后用户将 window/tab 移动到新的 URL,服务器将不一定知道连接无法正常工作而不依赖 ping/pong 输入信号以定期测试连接。

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

如果 computer/OS 崩溃,套接字可能不会正常关闭(尽管这可能在某种程度上 OS 依赖并且也可能依赖于崩溃)。