2

我正在寻找对网站上的“通知”系统进行长时间轮询。我以前从未这样做过,因此我正在网上寻找有关它的信息。我在这里看:http: //techoctave.com/c7/posts/60-simple-long-polling-example-with-javascript-and-jquery

在关于长轮询的部分中,它说:“超时:为请求设置超时(以毫秒为单位)。超时时间从 $.ajax 调用开始。在这里,我们将超时设置为 30 秒。这意味着在 ajax 调用完成并且(至少)三十 (30) 秒过去之前,我们的 poll 函数不会被再次调用。”

在 ajax 调用完成并且至少 30 秒过去之前,不会调用 poll。

但是,当我将其添加到 Javascript 中时,会在完成 ajax 调用所需的时间内一遍又一遍地调用 poll。它不会等待 30 秒。

(function poll() {

         $.ajax({ url: "/myapp/messages/messages/checkMessages", success:
         function(data){alert("YO");}, complete: poll, timeout: 30000 });

    })(); 

我是不是做错了什么,或者这是轮询应该工作多长时间?

另外,这样有效吗?这会随着网站流量而扩展吗?

谢谢您的帮助!

(function poll(){
           setTimeout(function(){
              $.ajax({ url: "/myapp/messages/messages/checkMessages", success: function(data){
                  console.log("Polling!");
              }, complete: poll, timeout: 30000});
          }, 30000);
        })();
4

4 回答 4

4

设置$.ajax呼叫超时只会设置呼叫的最大超时。

即,如果第一次调用$.ajax在超时时间内未完成,则将再次调用 poll。否则,如果调用完成,poll则将再次调用。如果在超时时间之前完成,这将导致poll重复调用。

下面将pollsetTimeout 包装起来,停止poll重复调用自身(如您在上面所做的那样)

(function poll(){
    setTimeout(function(){
        $.ajax({ url: "/myapp/messages/messages/checkMessages", success: function(data){
            console.log("Polling!");
        }, complete: poll, timeout: 30000});
    }, 30000);
})();

*注意:我已经为任何寻求更清晰的人添加了答案。

于 2013-03-14T07:37:44.097 回答
2

进行长轮询的原因是为了获得服务器推送的效果。这意味着服务器端存在不可预测的延迟,在此期间,理想情况下,客户端只是异步等待服务器发送消息。服务端无法发起与客户端的连接,所以客户端发起连接,然后等待服务端有话要说。

如果这是您的想法,那么没有理由对 AJAX 调用施加超时;好吧,有一个:如果您担心与服务器的连接可能会断开,或者服务器本身可能会无限期挂起,那么在 AJAX 调用上设置超时将导致客户端在给定时间后重新启动连接,不管服务器是否传输了任何东西。在没有与服务器断开连接的情况下,客户端超时完全没有区别。

最初的问题表明服务器会立即响应每个 ajax 请求,这听起来像是在客户端想要一个计时器(而不是超时)的原因是为了减慢与服务器的对话。如果是这样的话,这真的不是长轮询,它只是普通的轮询。简而言之,区别在于:通过轮询,客户端控制从服务器流出信息的时间和频率。通过长轮询,服务器控制时间和频率。整个想法是消除服务器发送数据和客户端处理该数据之间的任何延迟。在轮询端使用计时器来延迟来自服务器的响应会破坏该目的。

您可以在客户端进行有效的长轮询,而无需任何超时。正如已经提供的示例一样,使用“完整:”定义重新启动 ajax 请求;使用“成功”定义来处理任何数据。无论 XHR 成功与否,都会发生“完成”。

如果您想让它免受连接断开的影响,那么您可以通过在服务器端执行超时来实现死机切换。在服务器上,即使它没有要发送的数据,也要让它回复心跳。在成功:定义中,更新本地上次心跳时间。在完整的:定义中,恐慌或失败,或者当没有心跳超过服务器超时设置时做你想做的事情。

于 2013-12-04T06:01:55.903 回答
1

好像您遇到了会话文件锁定

对于 PHP

使用session_write_close()

于 2013-12-14T07:04:01.277 回答
0

complete如果无论如何都打算每 30 秒调用一次回调,则您看不到回调的必要性:

(function poll(delay){
    $.ajax({
        url: '/myapp/checkMessages',
        timeout: delay,
        success: function(data){
            console.log('Messages !');
        }
    });

    setTimeout(function(){ poll(delay); }, delay);
})(30000);
于 2013-10-22T08:31:53.840 回答