停止一段时间循环PHP

时间:2013-05-22 11:24:48

标签: php comet long-integer long-polling

对这个问题感兴趣 - 如何在睡眠中正确停止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();

}

3 个答案:

答案 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放在拉动数据库检查警报的网页上。否则你将遇到性能问题。