PHP + gzip:关闭连接并继续执行

时间:2009-10-09 00:22:57

标签: php flash apache gzip mod-deflate

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

我希望发生的是尽快将数据返回给客户端,关闭连接,然后执行客户端不必关心的所有内容。这可能会使API看起来更具响应性。遵循这里的建议:

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

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

似乎就像应该有办法让Apache知道“我已经发送了你要发送的所有数据”,但我似乎无法找到类似的东西

对于那些想知道的人,是的,我可以尽早清除结果,但Flash客户端将不会处理它们,直到连接关闭。

5 个答案:

答案 0 :(得分:3)

您可以尝试将其分成两页。

在第一页中,进行必要的处理,然后通过curl加载第二页,并使用die()。

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

即:

第1页:

<?php

// Do stuff

// Post or get second page...

// Send Data to client

die();
?>

第2页:

<?php

// Do other stuff....

?>

请参阅http://www.php.net/curl

答案 1 :(得分:0)

在通过register_shutdown_function();

注册的回调方法中,在连接关闭后放置要执行的代码,有一种方法可以做到这一点

答案 2 :(得分: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();

答案 3 :(得分: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个字节,代码“可能”会失败。

答案 4 :(得分:-1)

今天我也遇到了这个案例,经过一些测试后,我发现这种方式有效:

两个步骤:

  1. 确保php脚本输出不是gzip编码,解决方案可以参考这个link

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

  2. 将以上内容添加到prj网站下的.htaccess文件中,然后避免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.