【问题标题】:Codeigniter LongPolling "while(true)" does not work?Codeigniter LongPolling“while(true)”不起作用?
【发布时间】:2012-11-21 14:41:26
【问题描述】:

我目前正在 Codeigniter 中实现长轮询功能,但遇到了问题。

假设我有一个普通的 PHP 控制器:

function longpolling()
{
    //PHP Timelimit infinite
    set_time_limit(0);

       while(true){  
                    echo "test";

                   //Sleep 3 Seconds
                     sleep(3);
             }
}

页面只是在调用时表示正在加载,并且不返回“test”,而是在一段时间后得到 404 错误。

我做错了什么?

谢谢!

【问题讨论】:

  • 我刚刚检查了error.log 2012/11/21 17:52:04 [error] 28833#0: *45 upstream timed out (110: Connection timed out) while reading response header from upstream, client: XXX, server: _, request: "GET /index.php/notification/longpolling HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "XXX" 2012/11/21 17:52:04 [error] 28833#0: *45 open() "/usr/share/nginx/html/50x.html" failed (2: No such file or directory), client: XXX, server: _, request: "GET /index.php/notification/longpolling HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "XXX"
  • 您必须最终结束响应。查看以下帖子:Simple “Long Polling” example code?.
  • 使用 die() 可以防止任何进一步的回显输出

标签: php javascript html codeigniter long-polling


【解决方案1】:

您没有做任何“错误”的事情,只是 php 没有按照您期望的方式工作。

如果你这样做:

$i = 0;
while ($i < 10)
{
    echo "Hi There!";
    sleep(2);
    $i++;
}

它最终会输出很多 Hi There,但不是一次输出一个,而是在 while 循环结束时全部显示。

你甚至可以在里面扔一个flush()

$i = 0;
while ($i < 10)
{
    echo "Hi There!";
    flush();
    sleep(2);
    $i++;
}

直到最后你还是什么都得不到。

因为您的while(true) 永远不会结束,所以您将永远看不到任何输出,并且我假设浏览器超时开始了?还是达到max_execution_time设置?

现在突然出现在我的脑海中:如果您在无限循环中将一些数据写入文件可能会起作用,我自己从未尝试过。

【讨论】:

  • 您好,有一个使用 while(true) 的示例文件,这实际上是 longpolling 的本质?! code.google.com/p/jquery-longpolling。它在那里工作..
  • 据我了解(可能是错误的)如果请求永远不会关闭,这发生在没有中断的 while(true) 循环下,那么 jquery 不会触发 ajax 调用的成功事件?不过我可能错了。
  • 它会触发 ;) 您检查 jquery longpolling 中的示例文件。我在本地 XAMPP 服务器上尝试过。这就是为什么我很困惑为什么它在codeigniter中不起作用。 :)
  • 是的,我尝试了演示,但我不确定应该发生什么,但我等待了很长时间,然后所有结果都立即显示出来,而且只发生了一次?
  • 我明白了,尽管当文件更改时它仍然 exit() 是强制内容退出的脚本,但你的脚本将永远挂起,因为它永远不会退出!
【解决方案2】:

我自己也遇到过这样的问题。您必须考虑将输出刷新为 php 和/或网络服务器可能正在缓冲数据,直到达到某个阈值。我在 IIS 上为此苦苦挣扎,我认为 Apache 更容易管理。另外还有告诉网络服务器该做什么。对于 apache,这是在 php.net 上找到的 sn-p:

我只是在使用flush() 和ob_flush() 时遇到了一些问题。我做了什么 解决这个问题我花了一些时间来弄清楚所以我想 分享我的想法。

主要问题是 php 设置“output_buffering”可以 设置太大,会阻止您的文本输出。改变 您可以在 php.ini 中设置此值,也可以添加行

php_value output_buffering "0"

到您的 .htaccess 文件。它不适用于 ini_set() 因为它是 PHP_INI_PERDIR。

这与在 sleep() 之前使用的 flush() 函数相结合。在它开始正确刷新之前,我还必须输出多个字符:

    public function longpolling()
    {
        echo str_repeat(" ", 1024); flush();
        for( $i = 0; $i < 10; $i++) {
            echo $i."<br/>";
            flush();
            sleep(1);
        }
    }

还有。我只是在我的服务器上尝试了这个,直到我将 php_value 行添加到我的 htaccess 文件中才起作用。一旦我这样做了,它就按预期工作了。

【讨论】:

  • 这个例子适用于普通的 php localhost code.google.com/p/jquery-longpolling/.Why 这不能在 codeigniter 上工作吗?
  • 我已经更新了我的答案。与我的 pyrocms 一起工作的额外部分(基于 codeigniter,因此它应该可以工作)是放入 echo str_repeat(" ",1024); flush(); 行。那是在控制器内,并且该行是必要的。您可能需要也可能不需要先调整要输出的字符数。 1024 对我有用,但 700 没有。
【解决方案3】:

页面将一直加载,直到 PHP 文件执行到文件末尾。 PHP 不像 C 或 C++ 那样工作。你提出一个请求,当一切都完成后,你会得到输出。页面加载后,不再执行 PHP。

sleep() 在某些情况下只是用来减慢 PHP 的速度。在这种情况下:

echo "Something";
sleep(30);
echo " else";

“Something”和“else”将同时打印,而总执行时间将增加 30 秒。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多