对您的问题的简短回答
你的直觉是正确的。长轮询(又名彗星)将比直接轮询更有效。如果可用,websockets 将比长轮询更有效。那么为什么有些公司使用“拉式轮询”很简单:他们已经过时了,需要花一些时间来更新他们的代码库!
比较轮询、长轮询(彗星)和 WebSockets
使用传统轮询,您将重复发出相同的请求,通常将响应解析为 JSON 或将结果作为内容填充到 DOM 容器中。此轮询的频率与数据更新的频率没有任何关系。例如,您可以选择每 3 秒轮询一次新数据,但数据可能一次保持 30 秒不变?在这种情况下,您会浪费 HTTP 请求、带宽和服务器资源来处理许多完全无用的 HTTP 请求(在实际发生任何变化之前重复 9 次相同的数据)。
通过长轮询(又名彗星),我们显着减少了浪费。当您的请求发出更新数据时,服务器接受请求,但如果没有新更改则不响应,而是将请求保持打开 10、20、30 或 60 秒,或者直到一些新数据准备好它可以响应。最终请求将超时或服务器将响应更新。这里的想法是您不会像上面的 3 秒轮询那样经常重复相同的数据,但是您仍然可以非常快速地收到新数据的通知,因为可能已经有一个打开的请求正在等待服务器响应.
您会注意到长轮询大大减少了浪费,但仍有可能产生一些浪费。 30-60 秒是长轮询的常见超时时间,因为许多路由器和网关无论如何都会关闭挂起的连接。那么,如果您的数据实际上每 15 分钟更改一次呢?每 3 秒轮询一次会非常低效,但是在 60 秒超时的长轮询仍然会浪费一些到服务器的往返行程。
Websockets 是下一个技术进步,它将允许浏览器打开与服务器的连接并保持打开状态,并通过同一个打开的 Websocket 传递多个消息或数据块。然后,服务器可以在新数据准备好时准确地发送更新。 websocket连接已经建立,等待数据,快速高效。
现实检查
问题在于 Websockets 仍处于起步阶段。如果有的话,只有最新一代的浏览器支持它。截至本文发布时,该规范尚未得到完全批准,因此实现可能因浏览器而异。当然,您的访问者可能正在使用几年前的浏览器。因此,除非您可以控制访问者使用的浏览器(比如 IT 可以在工作站上指示软件的公司内部网),否则您将需要一种机制来抽象出该传输层,以便您的代码可以使用可用于该特定的最佳技术访问者的浏览器。
拥有抽象的通信层还有其他好处。例如,如果您的页面上有 3 个网格控件都每 3 秒拉一次轮询,看看这会是什么混乱?现在滚动你自己的长轮询实现可以清理一些,但如果你将所有这 3 个表的更新聚合到一个长轮询请求中会更酷。这将再次减少浪费。如果你有一个小项目,你也可以自己动手,但是有一个标准的Bayeux Protocol,许多服务器推送实现都遵循这个标准。 Bayeux 协议自动聚合用于传递的消息,然后通过“通道”(作为开发人员用于引导消息的任意类似路径的字符串)将消息分离出来。客户端可以监听频道,您可以在频道上发布数据,消息将到达所有监听您发布到的频道的客户端。
随着推送技术正在成为下一件大事,如今可用的服务器端服务器推送工具包的数量正在快速增长。那里可能有 20 个或更多的服务器推送工作实现。自己搜索“{Your favorite platform} comet implementation”,因为我敢肯定,它每隔几个月就会不断变化(并且之前已经在 stackoverflow 上介绍过)。