【问题标题】:WebSockets ping/pong, why not TCP keepalive?WebSockets ping/pong,为什么不是 TCP keepalive?
【发布时间】:2014-06-07 22:23:55
【问题描述】:

WebSockets have the option 向另一端发送 ping,另一端应该用 pong 响应。

在收到 Ping 帧后,端点必须发送 Pong 帧 响应,除非它已经收到关闭帧。这应该 尽快回复 Pong 框架。

TCPoffers something similarkeepalive形式:

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

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

此外,WebSockets are explicitly specified 始终通过 TCP 运行;它们与传输层无关,因此 TCP keepalive 始终可用:

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

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

【问题讨论】:

  • 实际上从来没有使用过 WebSocket ping/pong 因为no API was created。由于答案中提到的原因,一个人也从不使用 TCP keepalive。这是一个很好的例子,说明分层如何在不解决问题的情况下引入复杂性:每一层都必须实现相同的特性,但每一层都有其自身的用处。因此,应用程序仍然必须在所有其他层之上实现自己的 keepalive。

标签: tcp websocket keep-alive


【解决方案1】:

TCP keepalive的问题是:

  1. 默认关闭。
  2. 默认情况下每隔两小时运行一次,而不是像 Ping/Pong 协议那样按需运行。
  3. 它在代理之间运行,而不是端到端。
  4. 正如@DavidSchwartz 所指出的,它在 TCP 堆栈之间运行,而不是在应用程序之间运行,因此它不会告诉我们应用程序是否处于活动状态。

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

【讨论】:

  • 您可以使用setsockopt(2)在每个连接的基础上更改这两个。
  • @Thomas 您可以在某些平台上更改间隔。不是 Windows、FreeBSD、Solaris,...
  • 另外,它做错了事。我们想知道的是另一端的应用程序是否还活着。正如您所提到的,由于 TCP keepalive 是在内核中处理的,因此它们不会告诉我们另一端的应用程序是否处于活动状态。
  • @DavidSchwartz 我相信这是最重要的原因。也许把它变成一个答案?
  • 在 Ubuntu 中,我看到客户端大约每 30 秒左右发送一次 keepalive 确认,使用默认设置。它可以工作(我可以在远程非 Ubuntu 服务器 TCP 中设置 40 秒超时,并且连接仍然保持活动状态)。但是您关于过度分层的客户端、代理等的观点是更喜欢 WebSocket ping 的一个很好的理由。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

    .3.4 Ping 和 Pong 帧

    WebSocket 协议规范定义了 Ping 和 Pong 帧 可用于保持活动、心跳、网络状态探测、 延迟检测,等等。这些暂时没有曝光 在 API 中。

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

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

      • 我在接受这个或@vtortola 的回答之间犹豫不决,这两个都是很好的理由,但你还有一个赞成票,所以这里是:)
      • @Thomas 我很奇怪你接受了一个基于另一个更完整答案的答案。这里有几个答案重复了这个信息,还有几个更完整。
      • 你的……现在。代理问题是我遗漏的要点,而这不在您的原始答案中。
      • @Thomas 我说的是几个更好的答案,而不仅仅是一个。
      猜你喜欢
      • 2017-12-05
      • 2012-05-20
      • 2016-10-08
      • 2017-04-13
      • 2019-07-17
      • 2018-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多