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


74

WebSockets可以选择向另一端发送ping,而另一端应该以Pong响应。

收到Ping帧后,端点必须发送Pong帧作为响应,除非它已经接收到Close帧。在实际可行的情况下,应使用Pong框架进行响应。

TCP以keepalive形式提供类似的内容:

[Y]您向您的同伴发送一个没有数据的keepalive探测数据包,并且ACK标志已打开。由于TCP / IP规范(作为一种重复的ACK),您可以执行此操作,并且远程端点将没有参数,因为TCP是面向流的协议。另一方面,您将收到来自远程主机的答复(该主机根本不需要支持keepalive,仅支持TCP / IP),并且没有数据和ACK。

我认为TCP keepalive效率更高,因为它可以在内核中进行处理,而无需将数据传输到用户空间,解析websocket框架,制作响应框架并将其交还给内核进行传输。网络流量也更少。

此外,WebSockets被明确指定为始终在TCP上运行。它们与传输层无关,因此TCP keepalive始终可用:

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

那么,为什么要使用WebSocket ping / pong代替TCP keepalive?

Answers:


79

TCP keepalive的问题是:

  1. 默认情况下它是关闭的。
  2. 默认情况下,它每隔两个小时运行一次,而不是Ping / Pong协议提供的按需运行。
  3. 它在代理之间操作而不是端到端。
  4. 正如@DavidSchwartz指出的那样,它在TCP堆栈之间而不是在应用程序之间运行。

与WebSockets ping / pong的比较没有意义。TCP keepalive是自动的,并且在启用时是定时的,而WebSocket ping / pong是根据应用程序的要求执行的。


1
您可以使用在每个连接的基础上更改这两项setsockopt(2)
托马斯

3
@Thomas您可以在某些平台上更改时间间隔。不是Windows,FreeBSD,Solaris,...
user207421

15
另外,它做错了事。我们想知道的是另一端的应用程序是否仍在运行。正如您提到的,由于TCP keepalive是在内核中处理的,因此它们不会告诉我们另一端的应用程序是否仍在运行。
David Schwartz

1
@DavidSchwartz我相信这是最重要的原因。也许把这个变成答案?
Ashkan Kh。Nazary

在Ubuntu中,使用默认设置,我大约每30秒左右就会收到一次来自客户端的keepalive警报。它可以正常工作(我可以在远程非Ubuntu服务器TCP中设置40秒的超时,并且连接仍然有效)。但是您关于过度分层的客户端,代理等的观点是选择WebSocket ping的一个很好的理由。
personal_cloud

45

我认为除了EJP的答案以外,它还可能与HTTP代理机制有关。Websocket连接也可以通过(HTTP)代理服务器运行。在这种情况下,TCP keepalive将仅检查与代理之间的连接,而不检查端对端连接。


1
我在接受这个答案或@vtortola的答案之间感到痛苦,这两个都是很重要的原因,但是您的答案还多,所以这里是:)
Thomas

1
@Thomas我很好奇您接受了基于另一个更完整答案的答案。这里有几个重复这些信息的答案,还有几个更完整的答案。
user207421 '02

1
你的是...现在。代理人的事情是我所缺少的要点,而这并不是您最初的答案。
托马斯,

@Thomas我在谈论几个更好的答案,而不仅仅是一个。
user207421'6

20

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

.3.4乒乓球

WebSocket协议规范定义了Ping和Pong帧,它们可用于保持活动,心跳,网络状态探测, 等待时间检测等。这些当前未在API中公开。

用户代理可以根据需要发送ping和未经请求的pong帧,例如,尝试维护本地网络NAT映射,检测失败的连接或向用户显示延迟指标。用户代理不得使用ping或不请自来的pong来协助服务器;假定服务器会在适合服务器需求的情况下招募乒乓球。

WebSockets的开发考虑了RTC,因此,当我查看ping / pong功能时,我也看到了一种测量延迟的方法。pong必须返回与ping相同的有效负载,这使得发送时间戳非常方便,然后计算从客户端到服务器的延迟,反之亦然。


18

TCP keepalive不会通过Web代理传递。网络套接字的ping / pong将通过网络代理转发。TCP keepalive旨在监督TCP端点之间的连接。Web套接字端点不等于TCP端点。一个websocket连接可以在两个websocket端点之间使用多个TCP连接。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.