我建立了一个具有聊天功能的网站,我需要跟踪在线和离线用户。为了跟踪在线用户,我正在使用此表
user_id |时间戳
我为所有在线用户每20秒更新一次时间戳。所以我只需将当前时间戳与表格中的时间戳进行比较,就可以找出所有人都处于离线状态。
现在的问题是: 我使用长轮询来更新用户的在线状态。也就是当用户登录时,我对一个看起来像这样的脚本运行ajax调用。
<?php
set_time_limit(0);
while(1){
updateUserTimestamp();
sleep(20);
}
?>
上面的代码工作正常。但问题是,即使在用户关闭浏览器之后,它仍然像幽灵进程一样继续运行并继续更新时间戳并占用资源。我希望它在客户端关闭时停止浏览器。
请帮忙。
答案 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 :(得分:1)
但问题是,即使在用户关闭浏览器之后,它仍然像幽灵进程一样继续运行并继续更新时间戳并占用资源。我希望它在客户端关闭浏览器时停止。
这正是你不想这样做的原因。您需要删除此脚本,并将updateUserTimestamp()
移动到一个经常调用的全局脚本,理想情况下是用户状态更改的脚本(因为,如果没有用户状态更改,则不必更新任一)。
答案 2 :(得分:0)
你在运行这个服务器的服务器是什么?这不应该发生,因为当用户关闭浏览器时,它也应该终止AJAX请求并关闭TCP连接,服务器应该注意这一点并终止正在运行的PHP进程/线程。
尝试添加一个window.onunload
客户端事件,该事件会终止所有活动的AJAX请求,看看是否会产生影响。
答案 3 :(得分:0)
您的代码会继续更新状态,而不会提供用户仍处于连接或处于活动状态的任何证据。如果用户只是关闭他的计算机,它将永远运行,即使它可以检测到连接关闭。 (关闭的计算机无法关闭连接,可以吗?)
您必须让用户每隔20秒执行一次触发更新的操作。你可以决定它是什么,它可以是任何东西。但是用户必须做的事情让你觉得他很活跃。你不能只考虑他永远活跃,这就是你的代码所做的。
答案 4 :(得分:-1)
为了避免永不终止进程,让脚本在等待20秒后终止,并强制客户端打开新连接。你保留了长轮调的优点,但不会再有鬼程。