【问题标题】:Long polling server loop长轮询服务器循环
【发布时间】:2014-04-16 17:28:45
【问题描述】:

我正在尝试制作传入消息的通知系统。例如,用户停留在页面上,他在一个块中收到他有 2 条未读消息。

我的客户代码:

(function getmess(){
var id = '<?=$MY_ID;?>';
    $.ajax({
      url:"notif.php",
      data:{"id":id,},
      type:"GET",
      success: function(result){
        $("#count").html(result);
      }, dataType: "json",
      complete: getmess,
      timeout: 10000});
})();

我的服务器代码:

<?php
    $mysqli = new mysqli('localhost', 'root', '', 'lc');
    if (mysqli_connect_errno()) { 
        printf("error: %s\n", mysqli_connect_error()); 
        exit; 
    }  

$MY_ID = $_POST['id'];

while (true) {
$result = $mysqli->query("SELECT COUNT(*) FROM messages WHERE user_get='$MY_ID' AND status='0' ");
if (mysqli_num_rows($result)) {
while ($row = mysqli_fetch_array($result)) {
echo $row[0]."";
}
exit;
}
sleep(5);
}

一切正常,但我遇到的问题是 ajax 请求每 1 秒发送一次,这些请求的长度为 1 秒,它们会使服务器过载。

我想等待服务器响应至少10秒,在响应成功的情况下立即发送新请求,以及如果服务器在10秒内没有响应,即在数据库中有没有变化,然后发送一个 10 秒的新查询长度。

我认为服务器有问题(可能是服务器循环),但我不知道如何改进。

【问题讨论】:

  • 我建议改用 websockets。
  • 您的客户端代码有问题,而不是服务器。你必须用setTimeout 包裹getmess 电话。

标签: php ajax long-polling


【解决方案1】:

很抱歉,这行不通,因为对于每个用户,您的服务器都有一个开放线程。很快就会变得非常沉重。

最好只轮询服务器,即。每分钟一次,然后让服务器只处理一次该请求,而不是保持打开状态。

这是可能的,只是 PHP 不行。以http://cometd.org/ 为例。

【讨论】:

    【解决方案2】:

    虽然还有其他选项可用,但如果您使用轮询,您需要解决一些问题:

    • 不要使用间隔进行轮询,而是使用您在 ajax 请求的成功函数中设置的超时。这样您就不必担心请求重叠。
    • 当 javascript 进行轮询时,不要在 php 中使用循环来轮询新的数据库条目。只需检查一次并将结果返回给浏览器。
    • 注意数据库没有变化是正常的,成功的数据库 查询,以便您可以只发回一个空结果。我会返回 json 使用数据库条目列表或空列表(如果未找到)并在 javascript 中处理这些结果。

    简而言之,只需在 php 中快速检查您的数据库,然后在 javascript 中处理其余部分。

    【讨论】:

    • 但是如何强制我的脚本等待 10 或 20 秒以等待来自服务器的响应而不是 1 秒?
    • @user3140144 您的脚本不必等待那么久,响应应该是即时的。等待应该在 JavaScript 中完成,例如使用 setTimeout()
    • 是的,但是长轮询意味着我们等待例如 20 秒以等待来自服务器的响应(在我的情况下:如果数据库已更改),如果某些东西立即更改服务器响应,但如果没有任何改变,我们发送新请求并再次等待 20 秒。
    • @user3140144 不,您不等待服务器 20 秒,而是等待 20 秒再发出新的 ajax 请求。
    • 但是如何在客户端和服务器之间保持 20 秒的连接,而不是每秒检查数据库中是否出现了某些内容?
    猜你喜欢
    • 2013-05-25
    • 1970-01-01
    • 2019-02-10
    • 1970-01-01
    • 2015-11-20
    • 2012-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多