WebSockets 在什么时候比轮询效率低?

At what point are WebSockets less efficient than Polling?

虽然我知道上述问题的答案在某种程度上取决于您的应用程序架构,但我主要对非常简单的场景感兴趣。

本质上,如果我的应用程序每 5 秒或每分钟 ping 一次以进行更改,那么发送以维持打开的 Web 套接字连接的数据大约何时会超过简单轮询浪费的数据量?

基本上,我感兴趣的是,如果应用程序不一定需要实时更新,而只需要定期检查,是否有一种方法可以量化使用 Meteor 等框架所导致的效率低下程度。

请注意,我这里的重点是带宽利用率,不一定是数据库访问时间,因为像 Meteor 这样的框架具有高度优化的方法,只请求更新数据库。

websocket 连接的全部意义在于您永远不必通过 ping 应用程序来获取更改。相反,客户端只需连接一次,然后服务器可以在可用时直接发送客户端更改。客户永远不必问。服务器只在数据可用时发送数据。

对于任何类型的 server-initiated-data,这在带宽方面比 http 轮询更有效。除了为您提供更及时的结果(结果会立即传送,而不是仅在下一个轮询间隔才由客户端发现)。

对于纯粹的带宽使用,细节将取决于具体情况。 http 轮询请求必须建立 TCP 连接并确认该连接(如果是 SSL 连接,则需要更多数据),然后它必须发送 http 请求,包括属于该主机的任何相关 cookie,包括相关 headers 和 GET URL。然后,服务器必须发送响应。而且,大多数时候,所有这些轮询开销都将完全浪费带宽,因为没有新内容可报告。

一个webSocket从一个简单的http请求开始,然后将协议升级为webSocket协议。在服务器有东西要发送给客户端之前,webSocket 连接本身根本不需要发送任何数据,在这种情况下,服务器只发送数据包。发送数据本身的开销也少得多。没有 cookie,没有 headers,等等……只有数据。即使您在 webSocket 上使用一些 keep-alives,与 HTTP 请求的开销相比,该数据量也非常小。

因此,您究竟要节省多少带宽取决于具体情况。如果它在找到任何有用数据之前需要 50 个轮询请求,那么与 webSocket 场景相比,这些 http 请求中的每一个都完全被浪费了。带宽的差异可能是巨大的。

您询问了一个只需要定期检查的应用程序。一旦您进行定期检查导致没有数据被检索到,那就是带宽浪费。这就是 webSocket 的全部思想。当没有数据要发送时,您不消耗带宽(或接近不消耗带宽)。

相信@jfriend00 回答的很清楚了。但是,我确实想补充一点。

通过抛出 Websockets 与 HTTP 的最坏情况(并且不太可能),您会清楚地看到 Websocket 连接在带宽(可能 all-round 性能)方面始终具有优势。

这是 Websockets 的最坏情况 v/s HTTP:

  • 您的代码使用 Websocket 连接的方式与使用 HTTP 请求的方式完全相同,用于轮询。

    (这不是你会做的事情,我知道,但这是最坏的情况)。

  • 每个轮询事件都得到肯定的回答 - 这意味着没有徒劳地执行 HTTP 请求。

对于 Websockets 来说,这是最糟糕的情况,它是为推送数据而不是轮询而设计的……即使在这种情况下,Websockets 也会为您节省带宽和 CPU 周期。

说真的,即使忽略 DNS 查询(由客户端执行,所以你可能不关心它)和 TCP/IP 握手(这对客户端和服务器来说都是昂贵的),一个 Websocket 连接性能仍然更高 cost-effective.

我来解释一下:

每个 HTTP 请求都包含大量数据,例如 cookie 和其他 headers。在许多情况下,每个 HTTP 请求也需要经过客户端身份验证……数据很少会泄露给任何人。

这意味着 HTTP 连接传递所有这些数据(并可能执行客户端身份验证)每个请求一次。[无状态]

但是,Websocket 连接是有状态的。数据只发送一次(而不是每次发出请求时)。客户端身份验证仅在 Websocket 连接协商期间发生。

这意味着 Websocket 连接传递相同的数据(并可能执行客户端身份验证)每个连接一次(所有轮询一次)。

所以即使在这种最坏的情况下,轮询总是积极的并且 Websockets 用于轮询而不是推送数据,Websockets 仍然会节省您的服务器带宽和其他资源(即 CPU 时间)。

我认为您的问题的答案简单来说就是“从不”。 Websockets 的效率永远不会低于轮询。