当前位置:  开发笔记 > 编程语言 > 正文

早点关闭连接

如何解决《早点关闭连接》经验,为你挑选了5个好方法。

我正在尝试进行AJAX调用(通过JQuery),这将启动一个相当长的过程.我希望脚本只是发送一个响应,表明进程已经启动,但是在PHP脚本运行完毕之前,JQuery不会返回响应.

我用"关闭"标题(下面)尝试了这个,还有输出缓冲; 似乎都不起作用.任何猜测?或者这是我在JQuery中需要做的事情?


Joeri Sebrec.. 85

以下PHP手册页(包括用户注释)提供了有关如何在不结束PHP脚本的情况下关闭与浏览器的TCP连接的多条指令:

连接处理文档

据说它需要的不仅仅是发送一个关闭标题.


然后OP确认:是的,这就是诀窍: 指向用户注释#71172(2006年11月)复制到这里:

在保持php脚本运行的同时关闭用户浏览器连接一直是一个问题,因为[PHP] 4.1,当register_shutdown_function()修改了行为以便它不会自动关闭用户连接时.

sts at mail dot xubion dot hu发布原始解决方案:


其中,直到你代替工作正常phpinfo()进行echo('text I want user to see');在这种情况下,头永远不会发送!

解决方案是在发送标头信息之前明确关闭输出缓冲并清除缓冲区.例:


只花了3个小时试图弄清楚这一个,希望它能帮助别人:)

测试中:

IE 7.5730.11

Mozilla Firefox 1.81


后来在2010年7月的一个相关答案中, Arctic Fire随后将另外两个用户注释与后续用户注释相关联:

连接处理用户注释#89177(2009年2月)

连接处理用户注释#93441(2009年9月)

是的,这就是诀窍:http://www.php.net/manual/en/features.connection-handling.php#71172 (7认同)

黑客和糟糕的Web浏览器仍然可以忽略连接关闭的HTTP标头,并获取其余的输出。确保接下来出现的内容不敏感。也许是ob_start(); 抑制一切:p (3认同)

添加fastcgi_finish_request(); 一直说要成功地关闭时,上述方法无效的连接.然而,在我的情况下,它阻止我的脚本执行持续,所以请谨慎使用. (3认同)


Timbo White.. 54

有必要发送这两个标题:

Connection: close
Content-Length: n (n = size of output in bytes )

由于您需要知道输出的大小,因此您需要缓冲输出,然后将其刷新到浏览器:

// buffer all upcoming output
ob_start();
echo "We'll email you as soon as this is done.";

// 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();

// if you're using sessions, this prevents subsequent requests
// from hanging while the background process executes
if (session_id()) session_write_close();

/******** background process starts here ********/

此外,如果您的Web服务器在输出上使用自动gzip压缩(即带有mod_deflate的Apache),这将无法工作,因为输出的实际大小已更改,并且Content-Length不再准确.禁用gzip压缩特定脚本.

有关更多详细信息,请访问http://www.zulius.com/how-to/close-browser-connection-continue-execution



1> Joeri Sebrec..:

以下PHP手册页(包括用户注释)提供了有关如何在不结束PHP脚本的情况下关闭与浏览器的TCP连接的多条指令:

连接处理文档

据说它需要的不仅仅是发送一个关闭标题.


然后OP确认:是的,这就是诀窍: 指向用户注释#71172(2006年11月)复制到这里:

在保持php脚本运行的同时关闭用户浏览器连接一直是一个问题,因为[PHP] 4.1,当register_shutdown_function()修改了行为以便它不会自动关闭用户连接时.

sts at mail dot xubion dot hu发布原始解决方案:


其中,直到你代替工作正常phpinfo()进行echo('text I want user to see');在这种情况下,头永远不会发送!

解决方案是在发送标头信息之前明确关闭输出缓冲并清除缓冲区.例:


只花了3个小时试图弄清楚这一个,希望它能帮助别人:)

测试中:

IE 7.5730.11

Mozilla Firefox 1.81


后来在2010年7月的一个相关答案中, Arctic Fire随后将另外两个用户注释与后续用户注释相关联:

连接处理用户注释#89177(2009年2月)

连接处理用户注释#93441(2009年9月)


是的,这就是诀窍:http://www.php.net/manual/en/features.connection-handling.php#71172
黑客和糟糕的Web浏览器仍然可以忽略连接关闭的HTTP标头,并获取其余的输出。确保接下来出现的内容不敏感。也许是ob_start(); 抑制一切:p
添加fastcgi_finish_request(); 一直说要成功地关闭时,上述方法无效的连接.然而,在我的情况下,它阻止我的脚本执行持续,所以请谨慎使用.

2> Timbo White..:

有必要发送这两个标题:

Connection: close
Content-Length: n (n = size of output in bytes )

由于您需要知道输出的大小,因此您需要缓冲输出,然后将其刷新到浏览器:

// buffer all upcoming output
ob_start();
echo "We'll email you as soon as this is done.";

// 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();

// if you're using sessions, this prevents subsequent requests
// from hanging while the background process executes
if (session_id()) session_write_close();

/******** background process starts here ********/

此外,如果您的Web服务器在输出上使用自动gzip压缩(即带有mod_deflate的Apache),这将无法工作,因为输出的实际大小已更改,并且Content-Length不再准确.禁用gzip压缩特定脚本.

有关更多详细信息,请访问http://www.zulius.com/how-to/close-browser-connection-continue-execution


如果您的服务器压缩输出,您可以使用`header("Content-Encoding:none\r \n")禁用它;`这样apache不会压缩它.
我发现````ob_flush()```行*是必要的.

3> Jorrit Schip..:

您可以使用Fast-CGI和PHP-FPM来使用该fastcgi_end_request()功能.通过这种方式,您可以在响应已发送到客户端时继续进行一些处理.

如何使用fastcgi_finish_request()的例子(2010年11月)

您可以在PHP手册中找到:FastCGI Process Manager(FPM) ; 但该功能并未在手册中进一步说明.这里摘自PHP-FPM:PHP FastCGI Process Manager Wiki:


fastcgi_finish_request()

适用范围:php功能类别:优化

此功能允许您加快某些php查询的实现.当脚本执行过程中的操作不影响服务器响应时,可以进行加速.例如,在页面形成并传递到Web服务器之后,可以在memcached中保存会话.fastcgi_finish_request()是一个PHP功能,它会停止响应输出.Web服务器立即开始向客户端"缓慢而悲伤地"传输响应,并且php同时可以在查询的上下文中执行许多有用的操作,例如保存会话,转换下载的视频,处理各种统计等

fastcgi_finish_request() 可以调用执行关机功能.


这是实际的答案!
如果您使用的是php-fpm-只需使用此功能-则无需使用标题和其他所有内容。节省了我很多时间!

4> diyism..:

完整版:

ignore_user_abort(true);//avoid apache to kill the php running
ob_start();//start buffer output

echo "show something to user";
session_write_close();//close session file on server side to avoid blocking other requests

header("Content-Encoding: none");//send header to avoid the browser side to take content as gzip format
header("Content-Length: ".ob_get_length());//send length header
header("Connection: close");//or redirect to some url: header('Location: http://www.google.com');
ob_end_flush();flush();//really send content, can't change the order:1.ob buffer to normal buffer, 2.normal buffer to output

//continue do something on server side
ob_start();
sleep(5);//the user won't wait for the 5 seconds
echo 'for diyism';//user can't see this
file_put_contents('/tmp/process.log', ob_get_contents());
ob_end_clean();


这一行:header("Content-Encoding:none"); - >非常重要.

5> Salman A..:

更好的解决方案是派生后台进程。在unix / linux上是相当简单的:

/dev/null &");
?>

您应该查看此问题以获取更好的示例:

PHP执行后台进程

推荐阅读
地之南_816
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有