1

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

用户 ID | 时间戳

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

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

<?php
set_time_limit(0);

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

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

请帮忙。

4

5 回答 5

4

尝试以下解决方案(请参阅有关 connection_aborted() 函数的文档):

<?php
set_time_limit(0);

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

或者,您可以将脚本设置为在客户端关闭连接时中止。有关详细信息,请参阅文档ignore_user_abort

但是,如果您可能有许多并发请求,那么也许这是一个好主意

  1. 放弃使用长轮询来支持频繁的 AJAX 请求,或者
  2. 采用类似 Node.js 的服务器端解决方案,这些解决方案不会在额外请求上使用太多资源。
于 2011-09-01T09:23:00.890 回答
1

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

这正是你不想这样做的原因。您需要删除此脚本,并将其updateUserTimestamp()移至一些经常调用的全局脚本,最好是更改用户状态的脚本(因为,如果没有用户状态更改,也不必更新)。

于 2011-09-01T09:22:06.523 回答
0

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

尝试添加一个window.onunload客户端事件来终止所有活动的 AJAX 请求,看看是否有区别。

于 2011-09-01T09:21:45.553 回答
0

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

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

于 2011-09-01T09:42:54.460 回答
-1

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

于 2011-09-01T09:28:38.580 回答