【问题标题】:PHP longpolling running endlesslyPHP longpolling 无休止地运行
【发布时间】:2011-11-08 06:13:29
【问题描述】:

我正在构建一个具有聊天功能的网站,我需要跟踪在线和离线用户。为了跟踪在线用户,我正在使用此表

user_id |时间戳

我每 20 秒更新一次所有在线用户的时间戳。所以我可以通过将当前时间戳与表中的时间戳进行比较来找出谁都离线。

现在问题是这样的: 我使用长轮询来更新用户的在线状态。即当用户登录时,我对一个看起来像这样的脚本运行 ajax 调用。

<?php
set_time_limit(0);

while(1){
  updateUserTimestamp();
  sleep(20);
}
?>

上述代码运行良好。但问题是,即使在用户关闭浏览器后,它仍像幽灵进程一样继续运行,并不断更新时间戳并占用资源。我希望它在客户端关闭时停止浏览器。

请帮忙。

【问题讨论】:

  • 哇..你不想这样做。这使 PHP 进程在您的服务器上无限运行。您不能在应用程序的某个全局类/脚本中执行此操作吗?

标签: php ajax loops long-polling infinite


【解决方案1】:

尝试以下解决方案(请参阅the documentation on connection_aborted() function):

<?php
set_time_limit(0);

while(!connection_aborted()){
    updateUserTimestamp();
    sleep(20);
}

或者,您可以将脚本设置为在客户端关闭连接时中止。详情请见the documentation on ignore_user_abort。

但是如果你可能有很多并发请求,那么可能是一个好主意

  1. 放弃使用长轮询来支持频繁的 AJAX 请求,或者
  2. 采用类似 Node.js 的服务器端解决方案,不会在额外请求上使用太多资源。

【讨论】:

  • 我正在使用共享虚拟主机,无法安装任何新的服务器软件 :( 谢谢我会尝试上面的代码并发布结果
  • 赞成,因为这是最好的答案,但 OP 绝对应该牢记 Tadeck 的建议。像这样的服务器端 while () 循环绝不是一个好主意。
【解决方案2】:

但问题是,即使在用户关闭浏览器后,它仍像幽灵进程一样继续运行,并不断更新时间戳并占用资源。我希望它在客户端关闭浏览器时停止。

这正是您不想这样做的原因。您需要删除此脚本,并将updateUserTimestamp() 移动到某个经常调用的全局脚本,理想情况下是更改用户状态的脚本(因为,如果没有用户状态更改,也不必更新) .

【讨论】:

    【解决方案3】:

    您在哪个服务器上运行它?这不应该发生,因为当用户关闭浏览器时,它也应该终止 AJAX 请求并关闭 TCP 连接,服务器应该注意到这一点并终止正在运行的 PHP 进程/线程。

    尝试添加一个window.onunload 客户端事件,该事件会终止所有活动的 AJAX 请求,看看是否会产生影响。

    【讨论】:

      【解决方案4】:

      您的代码会继续更新状态,但没有任何证据表明用户仍处于连接状态或处于活动状态。如果用户只是简单地关闭他的计算机,即使它可以检测到连接关闭,它也会永远运行。 (关闭的计算机无法关闭连接,可以吗?)

      您必须让用户每 20 秒执行一次触发更新的操作。你可以决定那个东西是什么,它可以是任何东西。但是必须有用户做的事情让你认为他是活跃的。你不能仅仅认为他永远活跃,这就是你的代码所做的。

      【讨论】:

        【解决方案5】:

        为避免从不终止进程,请让脚本在等待 20 秒后终止,并强制客户端打开新连接。您保留了长轮询的优势,但不会再有幽灵进程。

        【讨论】:

          猜你喜欢
          • 2017-01-08
          • 1970-01-01
          • 2022-10-25
          • 2019-08-16
          • 1970-01-01
          • 2021-06-01
          • 2019-05-27
          • 1970-01-01
          • 2023-03-23
          相关资源
          最近更新 更多