5

我负责 API 的后端部分,用 PHP 编写,主要由 Flash 客户端使用。现在发生的事情是:Flash 客户端进行调用,后端加载必要的数据,进行任何必要的处理和后处理,记录和缓存,然后将结果返回给客户端。

我希望发生的事情是尽快将数据返回给客户端,关闭连接,然后做所有客户端不必关心的事情。这可以使 API 看起来更具响应性。按照这里的建议:

http://php.net/manual/en/features.connection-handling.php

实际上有效,除了我必须关闭 gzip 编码才能使其工作,这不是很实用。我们在 apache 中使用 mod_deflate,因此可以使用的解决方案是理想的,但如果有必要,我也会考虑另一种方法来压缩我们的内容。

似乎应该有一种方法让 Apache 知道“我已经向你发送了我要发送的所有数据”,但我似乎找不到类似的东西。

对于那些想知道的人,是的,我可以提前刷新结果,但是 Flash 客户端在连接关闭之前不会处理它们。

4

5 回答 5

3

你可以试着把它分成两页。

在第一页中,做必要的处理,然后通过 curl 加载第二页,然后 die()。

这将导致第一页完成并关闭,而与第二页处理无关。

IE:

第 1 页:

<?php

// Do stuff

// Post or get second page...

// Send Data to client

die();
?>

第2页:

<?php

// Do other stuff....

?>

http://www.php.net/curl

于 2009-10-09T00:38:00.343 回答
0

There's a kind of hack to do this by placing the code you want to execute after the connection closes within a callback method registered via to register_shutdown_function();

于 2009-10-09T02:04:06.597 回答
0
set_time_limit(0);
header("Connection: close");
header("Content-Length: " .(strlen($stream)+256));
ignore_user_abort(true);

echo $stream;
echo(str_repeat(' ',256));
@ob_flush();
@flush();
 @ob_end_flush();

your_long_long_long_long_function_here();

这将告诉用户在$stream收到所有内容后关闭连接。header但请注意不要在您知道的部分之前回显任何内容:p

如果您要发送二进制数据 (swf),您可能需要删除“+256”,echo(str_repeat(' ',256));但在这种情况下,如果发送的数据小于 256 字节,代码“可能”会失败。

于 2011-04-04T16:33:29.760 回答
0

@Theo.T 因为评论系统从我的代码中弄乱了垃圾,所以我把它贴在这里:

没运气。以下打印出额外的废话,并在使用 mod_deflate 时花费完整的执行时间来关闭连接:

function sleepLongTime() { 
    print "you can't see this";
    sleep(30);
}
ob_end_clean();
register_shutdown_function('sleepLongTime');
header("Connection: close\r\n");
ignore_user_abort(true);
ob_start();
echo ('Text user will see');
ob_end_flush();
flush();
ob_end_clean();
die();
于 2009-10-09T18:32:01.677 回答
-1

今天我也遇到了这种情况,经过一番测试,我发现这种方法有效:

两步:

  1. 确保 php 脚本输出没有使用 gzip 编码,解决方法可以参考这个链接

    <IfModule mod_env.c>
    SetEnvIfNoCase Request_URI "\.php$" no-gzip dont-vary
    </IfModule>

将以上内容添加到.htaccessprj网站下的文件中,然后自动避免apache gzip。

  1. 正如一些人所说features.connection-handling.php

    set_time_limit(0); 
    ignore_user_abort(true);    
    // buffer all upcoming output - make sure we care about compression: 
    if(!ob_start("ob_gzhandler")) 
        ob_start();         
    echo $stringToOutput;    
    // get the size of the output 
    $size = ob_get_length();    
    // send headers to tell the browser to close the connection    
    header("Content-Length: $size"); 
    header('Connection: close');    
    // flush all output 
    ob_end_flush(); 
    ob_flush(); 
    flush();    
    // close current session 
    if (session_id()) session_write_close(); //close connection
    
    // here, do what you want.
    
于 2012-02-15T04:19:01.710 回答