周期性的Ajax POST调用与COMET/Websocket推送

3
在像Trello.com这样的网站上,我注意到在firebug控制台中它会频繁地和定期向服务器发出Ajax POST请求以从数据库中检索新数据并在有新内容时更新dom。
另一方面,像Facebook通知这样的机制似乎正在实现COMET推送机制。
每种方法的优缺点是什么,具体来说,我的问题是为什么Trello.com使用“拉”机制,因为我一直认为使用这种方法(尤其是由于它经常向服务器发送ping),似乎不是可扩展的解决方案-当越来越多的用户注册使用它的服务时?
1个回答

5

你的问题的简短回答

你的直觉是正确的。长轮询(又称comet)比直接轮询更有效率。而当websockets可用时,它们将比长轮询更有效率。那么为什么一些公司使用“拉取轮询”呢?很简单:他们已经过时了,需要花时间更新他们的代码库!

比较轮询、长轮询(comet)和WebSockets

传统轮询会重复发送相同的请求,通常将响应解析为JSON或将结果作为内容填充到DOM容器中。这种轮询的频率与数据更新的频率没有任何关系。例如,您可以选择每3秒轮询一次新数据,但也许数据在30秒内保持不变?在这种情况下,您浪费了HTTP请求、带宽和服务器资源来处理许多完全无用的HTTP请求(在实际有所改变之前重复9次相同的数据)。

使用长轮询(也称为comet),我们显着减少了浪费。当您的请求发送更新数据时,服务器接受请求,但如果没有新更改,则不会响应,而是保持请求开放10、20、30或60秒,直到有新数据准备好并且可以响应。最终,请求将超时或服务器将用更新回复。这里的想法是,您不会像上面的3秒轮询那样经常重复相同的数据,但您仍然可以非常快地通知新数据,因为可能已经有一个开放的请求正在等待服务器响应。
您会注意到,长轮询大大减少了浪费,但仍然存在一些浪费的机会。 30-60秒是长轮询的常见超时时间,因为许多路由器和网关在该时间之后会关闭挂起的连接。那么,如果您的数据每15分钟实际更改一次呢?每3秒轮询将非常低效,但具有60秒超时的长轮询仍将有一些浪费的往返到服务器。
Websockets是下一个技术进步,它允许浏览器与服务器建立连接并保持打开状态,以便通过同一开放的websocket传递多个消息或数据块。当有新数据准备好时,服务器可以发送更新。由于websocket连接已经建立并等待数据,因此速度快且高效。
现实情况是,Websockets仍处于起步阶段。只有最新一代的浏览器支持它(如果支持的话)。截至本文发布时,规范尚未完全批准,因此不同浏览器的实现可能会有所不同。当然,您的访问者可能正在使用几年前的浏览器。因此,除非您可以控制访问者使用的浏览器(比如企业内部网络,IT可以指定工作站上的软件),否则您需要一个机制来抽象出这个传输层,以便您的代码可以使用特定访问者浏览器可用的最佳技术。
有抽象的通信层还有其他好处。例如,如果您在页面上有3个网格控件,每3秒轮询一次,看看这会是多么混乱?现在,自己编写长轮询实现可以清理一些,但如果将所有3个表的更新聚合到一个长轮询请求中,那就更酷了。这将再次减少浪费。如果您有一个小项目,您可以自己制作,但有一个标准的Bayeux Protocol,许多服务器推送实现都遵循。Bayeux协议会自动聚合消息进行传递,然后按“频道”(开发人员用于指导消息的任意类似路径的字符串)将消息隔离出来。客户端可以监听频道,您可以在频道上发布数据,消息将传递到所有监听您发布到的频道的客户端。

随着推送技术成为下一个大趋势,可用的服务端推送工具包数量正在迅速增长。目前可能有20个或更多的服务端推送实现版本可供使用。您可以自行搜索“{您喜欢的平台}彗星实现”,我相信它将会每几个月就有变化(并且之前已经在stackoverflow上进行过讨论)。


感谢您对轮询和长轮询(“彗星推送”)之间差异的全面描述,这里有一个与您提到的bayeux协议相关的有趣问题 - https://dev59.com/L3NA5IYBdhLWcg3wcNbF - Calvin Cheng

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接