WebSockets ping/pong,为什么不是 TCP keepalive?

WebSockets有选择权向另一端发送 ping 信息,而另一端应该使用 pong 来响应。

在接收到一个乒乓帧后,端点必须发送一个乒乓帧到 响应,除非它已经收到一个关闭帧。它应该 在实际可行的情况下尽快响应乒乓画面。

Keepalive 形式的 TCP 提供了类似的东西:

[ Y ]您发送给您的对等端一个保持活动的探测数据包,其中没有任何数据,并且 ACK 标志打开。您可以这样做,因为 TCP/IP 规范是一种重复的 ACK,而且远程端点没有参数,因为 TCP 是面向流的协议。另一方面,您将收到来自远程主机的响应(它根本不需要支持 keepalive,只需要 TCP/IP) ,没有数据和 ACK 集。

我认为 TCP keepalive 更有效率,因为它可以在内核中处理,而不需要将数据传输到用户空间,解析一个 websocket 帧,构建一个响应帧,然后将其交还给内核进行传输。网络流量也更少。

此外,WebSockets是显式指定的总是运行在 TCP 之上; 它们不是不可知的传输层,所以 TCP keepalive 总是可用的:

WebSocket 协议是一个独立的基于 TCP 的协议。

那么,为什么要使用 WebSocket ping/pong 而不是 TCP keepalive 呢?

66869 次浏览

The problems with TCP keepalive are:

  1. It is off by default.
  2. It operates at two-hour intervals by default, instead of on-demand as the Ping/Pong protocol provides.
  3. It operates between proxies rather than end to end.
  4. As pointed out by @DavidSchwartz, it operates between TCP stacks, not between the applications so therefore it doesn't tell us whether the application is alive or not.

The comparison with WebSockets ping/pong isn't meaningful. TCP keepalive is automatic, and timed, when enabled, whereas WebSocket ping/pong is executed as required by the application.

Besides the answer of EJP I think it might be also related to HTTP proxy mechanisms. Websocket connections can also run through a (HTTP) proxy server. In such cases the TCP keepalive would only check the connection up to the proxy and not the end-to-end connection.

http://www.whatwg.org/specs/web-apps/current-work/multipage/network.html#ping-and-pong-frames

.3.4 Ping and Pong frames

The WebSocket protocol specification defines Ping and Pong frames that can be used for keep-alive, heart-beats, network status probing, latency instrumentation, and so forth. These are not currently exposed in the API.

User agents may send ping and unsolicited pong frames as desired, for example in an attempt to maintain local network NAT mappings, to detect failed connections, or to display latency metrics to the user. User agents must not use pings or unsolicited pongs to aid the server; it is assumed that servers will solicit pongs whenever appropriate for the server's needs.

WebSockets have been developed with RTC in mind, so when I look at the ping/pong functionality, I see a way of measuring latency as well. The fact that the pong must return the same payload as the ping, make it very convenient to send a timestamp, and then calculate latency from client to server or vice verse.

TCP keepalive doesn't get passed through a web proxy. The websocket ping/pong will be forwarded by through web proxies. TCP keepalive is designed to supervise a connection between TCP endpoints. Web socket endpoints are not equal to TCP endpoints. A websocket connection can use several TCP connections between two websocket endpoints.