我看到了这些用javascript显示轮询与长轮询的例子,但我不明白它们之间的区别。特别是对于长轮询示例,它是如何保持连接打开的?
这就是传统的轮询场景:
(function poll(){
setTimeout(function(){
$.ajax({ url: "server", success: function(data){
//Update your dashboard gauge
salesGauge.setValue(data.value);
//Setup the next poll recursively
poll();
}, dataType: "json"});
}, 30000);
})();
这是一个长轮询示例:
(function poll(){
$.ajax({ url: "server", success: function(data){
//Update your dashboard gauge
salesGauge.setValue(data.value);
}, dataType: "json", complete: poll, timeout: 30000 });
})();
谢谢!
不同之处在于:长轮询允许某种事件驱动的通知,因此服务器能够主动向客户端发送数据。可以说,正常的轮询是定期检查要获取的数据。维基百科对此非常详细:
对于长轮询,客户端以类似于正常轮询的方式向服务器请求信息;然而,如果服务器没有任何可供客户端使用的信息,则服务器不发送空响应,而是保留请求并等待信息变得可用(或等待合适的超时事件),之后最终向客户端发送完整的响应。
长轮询减少了需要发送的数据量,因为服务器只有在真正有IS数据时才发送数据,因此客户端不需要每隔一段时间检查一次。
如果您需要一种更高性能(而且imho更优雅)的全双工客户端/服务器通信方式,请考虑使用WebSocket协议,这太棒了!
这里没有明确描述最重要的事情:长轮询是在服务器端实现的。
这就是为什么用于长轮询和轮询的Javascript代码看起来大致相同——客户端实际上没有做任何不同的事情。";这个端点是立即响应还是等到它有一个非空响应"是驻留在Web服务器上的服务器端代码。
您的服务器决定何时响应。如果它决定有时可能会等待,那么这是一个漫长的民意调查。
-
对内存进行一些更改并返回的端点代码是一个定期轮询。
-
进行慢速SQL查询并立即返回的端点代码是常规轮询。
-
端点代码检查消息队列,发现它是空的,让线程休眠一段时间,然后再次检查它,直到队列有东西为止,这是一个长轮询。
客户端在任何情况下都只是等待。
-
在";常规的";轮询时,响应通常会很快返回,这取决于延迟和服务器处理请求所需的时间。
-
在";"长";轮询时,如果服务器只需要短暂等待,直到有东西需要响应,那么响应可能仍然会很快返回。但这也可能需要一段时间,因为服务器愿意拖延响应,以便用有用的东西进行响应。
从客户的角度来看,基本上是一样的。它发送一个请求,并在某个时刻得到响应。对于长轮询,可能会长一点,但不一定。
请注意,连接可能会超时,因此示例代码不会在生产中使用。您可能希望对超时和错误响应进行一些处理,通常只是重试请求。
因此,就我的一分钱而言,我认为您应该将选项2视为进行任何形式的轮询的更好方式。只在响应(成功/失败)之后才轮询服务器,这样会更干净/更高效。这几乎是使用递归和timeout
而不是setTimeout