【发布时间】:2013-05-22 11:24:47
【问题描述】:
对这个问题感兴趣 - 如何正确停止带有 sleep 的 while 循环。 我实施了“long poll”来快速更新网站上的信息(警告、其他信息)。
脚本的本质
1.我们会将GET-request发送到脚本所在的PHP-page。
2.脚本运行循环while。
3.在本系列中,有 2 个条件和最后的 sleep(1),这会暂停循环的执行。
- 如果循环运行更多秒 30 - 分别停止循环和脚本的执行。
-如果您的网站有新信息,请说“提醒” - 将结果提供给用户并停止循环。
问题 如果用户关闭浏览器窗口或重新加载页面 - 在脚本上执行一个新查询,这将再次开始循环。但是在这种情况下,循环 while 的先前执行将不会停止,直到它们至少在其中工作了一个条件。如果用户向页面发送大量请求 - 服务器的内存开始启动,结果全部挂起,直到所有 while 都不会停止执行。
问题 如何停止循环和脚本作为一个整体,当您运行页面时重新加载或客户端? 此刻我做了以下事情。 当您运行我们生成的脚本时,我们会收到一个分配给变量的随机数,并且与会话相同。进一步内陆同时做一个条件,其中变量必须是会话的值。如果为假 - 停止循环。 如果我们在 new 上运行脚本 - 会话的值会发生变化,因此所有先前的性能都会在停止时发生变化。 我可以使用那个选项吗?多少是安全的?
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();
}
【问题讨论】:
-
while (TRUE) -
可以使用继续;用于在循环内终止循环的关键字。
-
你真的需要 session_write_close(); / session_start(); ?更新过程是如何启动的,是否可以简单地将超时设置为 30 秒?
-
如何在javascript中使用
setInterval进行循环,并将脚本简化为没有循环的Session::instance()->get('user_update_key') == $key? -
如果用户手动开始对脚本执行大量请求 - 它会同时启动很多“while”,即加载服务器
标签: php comet long-integer long-polling