长轮询超时问题

5

我正在开发一个长轮询聊天室。但是当长轮询出现时,如果我在Chrome中刷新页面或尝试发送另一个异步请求,一切都会超时(即我无法再次加载我的域名直到我关闭/重新打开浏览器)。

我的客户端代码如下:

 $(document).ready(function() {
    setTimeout(
      function () {
        longPollForMessages();
      },
      500
    );
  });

function longPollForMessages()
{
  $.ajax({
    url: url,
    dataType: 'json',
    success: function(data) {     
        $('#chat_messages').append('<div>'+data.messages+'</div>');

        longPollForMessages();
    }
  });
}

我的服务器端:

while(true) {
      $messages = $db->getMessages();

      if (!$messages || sizeof($messages)==0) {
        sleep(1);
      } else {
        echo '{"message":'.json_encode($messages).'}';
        die();
      }
    }

有什么想法吗?假设没有语法错误。


尝试在服务器端代码中的echo后面加上break; - The Scrum Meister
谢谢你的回答 :) 我实际上已经有了那个,但是忘记在我的问题代码中包含它。所以那不是问题。 - Andy Hin
2
伙计们,我从这个问题中找到了答案:https://dev59.com/qlLTa4cB1Zd3GeqPcrPh - php会锁定给定的会话直到页面加载完成,因此第二个ajax调用无法通过。您必须通过调用session_write_close()来释放锁定。 - Andy Hin
你知道你将消息作为 message 返回,但在 JavaScript 中访问时要使用 messages 吗? - alex
Alex - 对不起,我只是快速重写了代码,因为我不想粘贴所有的内容(你可能不想读完它)。=) - Andy Hin
@Andy,请在回复中发布您评论中所说的答案,并将其接受为正确答案。 - Gabriele Petrioli
2个回答

0

我看到你已经回答了自己的问题,但是我最近遇到了类似的问题,并发现另一种处理方法是在ajax调用时禁用setTimeout,然后在success中重新启动它。这样,当服务器没有准备好提供信息时,你就不会频繁地向服务器发送请求。


据我所知,setTimeout只会调用一次函数。因此,在成功请求后,您仍需要重新启动调用。您能详细说明一下您的答案吗? - Andy Hin

0
我从这个问题中找到了答案:stackoverflow.com/questions/4457178/... - PHP会锁定一个给定的会话,直到页面加载完成,因此第二个ajax调用无法通过。您必须通过调用session_write_close()来释放锁定。

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