对这个问题感兴趣 - 如何在睡眠中正确停止while循环。 我实施了“长轮询”以快速更新网站上的信息(警告,其他信息)。
脚本的本质
1. 我们会将GET-request发送到脚本所在的PHP页面。
2。脚本在时运行。
3。在本系列中, 2 条件和最后的sleep(1)暂停执行循环。 - 如果循环运行更多秒 30 - 分别停止执行循环和脚本。 - 如果您的网站有新信息,请说“提醒” - 将结果导出给用户并停止循环。 问题
如果用户关闭浏览器窗口或重新加载页面 - 将在脚本上执行新查询,这将再次启动循环。但在这种情况下,先前执行循环而将不会停止,直到它们在其中至少有一个条件工作。如果用户向页面发送了大量请求 - 服务器的内存开始启动,结果全部挂起,直到所有而不会停止执行。 问题
当你运行页面重新加载或客户端时,如何停止循环和整个脚本?
目前我做了以下事情。
当您运行脚本时,我们生成的是接收分配给变量的随机数,并且与会话相同。进一步内陆的同时做一个变量必须是会话值的条件。如果错误 - 停止循环。
如果我们在新的上运行脚本 - 会话的值会发生变化,因此会停止所有先前的性能。
我可以使用那个选项吗?多少钱是安全的? UPDATE.PHP } // Initialize the user's session
$session = Session::instance();
$rand = rand();
$session->set('user_update_key', $rand);
$key = $rand;
$limit = 20;
$seconds = 0;
set_time_limit($limit + 1);
while (TRUE) {
if (Session::instance()->get('user_update_key') == $key) {
if (there are updates. if there is - output) {
echo 'update information';
flush();
exit;
}
if ($seconds == $limit) { // complete the loop at the expiration of the time.
echo 'Close';
flush();
exit;
}
$seconds++;
} else {
unset($session, $rand, $key, $notice, $mysession, $last_notice, $limit, $notise_return, $seconds);
flush();
exit;
}
session_write_close();
sleep(1);
session_start();
答案 0 :(得分:1)
请注意,通常PHP和Apache不适用于长轮询。我不知道你使用nginx时的情况,但几个月前我不得不在Apache上做一些长时间的轮询工作。在我们投入生产之前,一切都很好看。事实证明,Apache的局限性阻止了你保持持久的连接。
服务器在允许大约20个用户登录并打开3-4张网页后,被拒绝并拒绝接受任何新请求。还存在浏览器限制,使您无法与一个主机保持过多的http连接。但是有一些解决方法 - 使用子域名。
我试图弄清楚如何解决id,在StackOverflow上问了十几个问题,一切都以使用node.js + socket.io结束,这是轻量级的,可以轻松处理数千个同时连接。
我知道这篇文章不能回答你原来的问题,但是在我开发了一些无效的东西后,我希望你能发现这些信息有用。
答案 1 :(得分:0)
你的状况是不可改变的,而在实践中却不是。 如果成功,函数sleep()将返回0,因此如果你在sleep()的返回值更改时重写while条件反应,那么它可能按设计工作,请参阅: http://php.net/manual/en/function.sleep.php
通过线程和其他功能,了解您正在使用的操作系统始终非常重要。我有Ubuntu,它的反应与文档说明不同。
function interruptedSleep(){
$cond = true;
while($cond){
$i = sleep(10);
if($i == 0){
$cond = false;
}
}
}
当您通过关闭浏览器来中断睡眠时,睡眠功能将返回0并且while循环将被中止,程序将在while之后直接继续。它不会抛出异常。
答案 2 :(得分:0)
为什么不使用cronjob定期在后台运行进程,然后将AJAX放在拉动数据库检查警报的网页上。否则你将遇到性能问题。