PHP longpolling无休止地运行

时间:2011-09-01 09:17:55

标签: php ajax loops long-polling infinite

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

user_id |时间戳

我为所有在线用户每20秒更新一次时间戳。所以我只需将当前时间戳与表格中的时间戳进行比较,就可以找出所有人都处于离线状态。

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

<?php
set_time_limit(0);

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

上面的代码工作正常。但问题是,即使在用户关闭浏览器之后,它仍然像幽灵进程一样继续运行并继续更新时间戳并占用资源。我希望它在客户端关闭时停止浏览器。

请帮忙。

5 个答案:

答案 0 :(得分:4)

尝试以下解决方案(请参阅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的服务器端解决方案,这些解决方案在其他请求上没有使用太多资源。

答案 1 :(得分:1)

  

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

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

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

您的代码会继续更新状态,而不会提供用户仍处于连接或处于活动状态的任何证据。如果用户只是关闭他的计算机,它将永远运行,即使它可以检测到连接关闭。 (关闭的计算机无法关闭连接,可以吗?)

您必须让用户每隔20秒执行一次触发更新的操作。你可以决定它是什么,它可以是任何东西。但是用户必须做的事情让你觉得他很活跃。你不能只考虑他永远活跃,这就是你的代码所做的。

答案 4 :(得分:-1)

为了避免永不终止进程,让脚本在等待20秒后终止,并强制客户端打开新连接。你保留了长轮调的优点,但不会再有鬼程。