PHP长轮询无休止地运行
我正在建立一个具有聊天功能的网站,我需要跟踪在线和离线用户。为了跟踪在线用户,我使用此表 用户id时间戳 我每20秒更新一次所有在线用户的时间戳,这样我就可以通过将当前时间戳与表中的时间戳进行比较来找出所有离线用户 现在的问题是: 我使用长轮询来更新用户的在线状态PHP长轮询无休止地运行,php,ajax,loops,long-polling,infinite,Php,Ajax,Loops,Long Polling,Infinite,我正在建立一个具有聊天功能的网站,我需要跟踪在线和离线用户。为了跟踪在线用户,我使用此表 用户id时间戳 我每20秒更新一次所有在线用户的时间戳,这样我就可以通过将当前时间戳与表中的时间戳进行比较来找出所有离线用户 现在的问题是: 我使用长轮询来更新用户的在线状态 <?php set_time_limit(0); while(1){ updateUserTimestamp(); sleep(20); } ?> 上面的代码工作得很好。但问题是,即使在用户关闭浏览器后,它
<?php
set_time_limit(0);
while(1){
updateUserTimestamp();
sleep(20);
}
?>
上面的代码工作得很好。但问题是,即使在用户关闭浏览器后,它仍像幽灵进程一样继续运行,不断更新时间戳并占用资源。我希望它在客户端关闭浏览器时停止
请帮助。您在哪台服务器上运行此操作?这不应该发生,因为当用户关闭浏览器时,它还应该终止AJAX请求并关闭TCP连接,服务器应该注意这一点并终止正在运行的PHP进程/线程
尝试添加一个
窗口。onunload
客户端事件将终止所有活动的AJAX请求,并查看这是否有影响。您在哪台服务器上运行此操作?这不应该发生,因为当用户关闭浏览器时,它还应该终止AJAX请求并关闭TCP连接,服务器应该注意这一点并终止正在运行的PHP进程/线程
尝试添加一个窗口.onunload
客户端事件,该事件将终止所有活动的AJAX请求,并查看这是否会产生影响
但问题是,即使在用户关闭浏览器后,它仍像幽灵进程一样继续运行,不断更新时间戳并占用资源。我希望它在客户端关闭浏览器时停止
这正是你不想这样做的原因。您需要删除此脚本,并将updateUserTimestamp()
移动到一些经常调用的全局脚本,理想情况下是更改用户状态的脚本(因为,如果没有用户状态更改,也不必更新)
但问题是,即使在用户关闭浏览器后,它仍像幽灵进程一样继续运行,不断更新时间戳并占用资源。我希望它在客户端关闭浏览器时停止
这正是你不想这样做的原因。您需要删除此脚本,并将
updateUserTimestamp()
移动到一些经常调用的全局脚本,理想情况下是更改用户状态的脚本(因为,如果没有用户状态更改,也不必更新)。尝试以下解决方案(请参阅):
尝试以下解决方案(请参阅):
为了避免永远不终止进程,请让脚本在等待20秒后终止,并强制客户端打开新连接。您保留了长轮询的优点,但将不再有重影进程。为了避免进程永远不会终止,请让脚本在等待20秒后终止,并强制客户端打开新连接。您保留了长轮询的优点,但将不再有重影进程。您的代码将继续更新状态,而没有任何证据表明用户仍处于连接状态或活动状态。如果用户只是简单地关闭了他的计算机,它将永远运行,即使它可以检测到连接关闭。(关闭的计算机无法关闭连接,是吗?)
你必须让用户每20秒做一件触发更新的事情。你可以决定那东西是什么,它可以是任何东西。但是用户必须做一些事情让你认为他是活跃的。你不能仅仅认为他是永远活跃的,这就是你的代码所做的。 你的代码继续更新状态,没有任何证据表明用户仍然是连接的或活动的。如果用户只是简单地关闭了他的计算机,它将永远运行,即使它可以检测到连接关闭。(关闭的计算机无法关闭连接,是吗?)
你必须让用户每20秒做一件触发更新的事情。你可以决定那东西是什么,它可以是任何东西。但是用户必须做一些事情让你认为他是活跃的。你不能仅仅认为他是永远活跃的,这就是你的代码所做的事情。你不想这么做。这将保持PHP进程在服务器上以内联方式运行。你不能在你的应用程序中的一些全局类/脚本中这样做吗?哇。。你不想这么做。这将保持PHP进程在服务器上以内联方式运行。你不能在你的应用程序中使用一些全局类/脚本吗?我正在使用一个共享的web主机,无法安装任何新的服务器软件:(谢谢,我会尝试上面的代码并发布结果,因为这是最好的答案,但OP绝对应该牢记Tadeck的建议。服务器端while()
这样的循环从来都不是一个好主意。我正在使用一个共享的web主机,无法安装任何新的服务器软件:(谢谢,我会尝试上面的代码并发布结果,因为这是最好的答案,但OP绝对应该牢记Tadeck的建议。服务器端while()
像这样循环从来都不是个好主意。
<?php
set_time_limit(0);
while(!connection_aborted()){
updateUserTimestamp();
sleep(20);
}