PHP 在 Nginx 下主动断开连接 Connection Close 与 ignore

这两天弄个PHP调用 SVN 同步 update 多台服务器更新的程序,为了避免 commit 的时候不会被阻塞卡半天得想个办法只请求触发,而不需要等待程序 update 完成返回结果这样耗时太长,所以研究过了下如何让PHP主动断开连接的方法。搞了一下午,发现很多问题,还好最终还是弄出来了,主要是 Nginx 太坑。。


废话不多说,下面上代码:


/**
 * 主动断开与客户端浏览器的连接
 * 如果是 Nginx 服务器需要输出大于等于 fastcgi_buffer_size 缓存的数据才能即时输出 header 断开连接, 若还是不行可尝试关闭 gzip
 * 如: fastcgi_buffer_size 64k; 即: 需要 64*1024 字符(可多不可少),
 * 可使用 str_repeat(' ', 65536); 另外 str_repeat('          ', 6554); 这种方式其实生成速度更慢
 * @param nullstring $str 当前输出的内容, 若无需输出则设置为空
 */
public function connectionClose($str = null) {
    $str = ob_get_contents() . $str;
    // 若实际输出内容长度小于该值将可能导致主动断开失败
    header('Content-Length: '. strlen($str));
    Header::connectionClose();
    ob_start();
    echo $str;
    ob_flush();
    flush();
}

补充说明下:

对于 apache 一般没什问题,我一开始在 windows 上用的 xampp 调试的 没发现什么问题,结果到服务器上是 Nginx ,死活不行,崩溃了一下午,后来才反映过来是 Nginx 的 fastcgi_buffer 的问题。

各种情况测试了N多次,应该没什么 BUG 了。。。


另外再说说 ignore_user_abort() 函数的问题

当浏览器关闭后,决定程序是否还会在后台继续执行,(下图的例子中,你在测试时不一定非要设置为永不超时 limit 0 ,设置一两分钟就行了,否则可能重启 HTTP 服务需要很长时间)





简单来说,如果你要用户浏览器关闭后还需要程序继续执行,那么你必须加上下面这句代码:

ignore_user_abort(true);

但根据你后面程序(主要是 while 死循环)的情况不同而有些许不同:

一般在程序中你可以监控连接状态进行控制:

$isAborted = connection_aborted();
$status = connection_status();
if (0 !== $status  $isAborted) {
    break;
}

但这两个函数要想正常工作得有个前提,就是你的程序必须要有输出内容,且大于当前WebServer 的输出缓存,这样才会起作用。

如果你只是简单的输出一个空格 echo ’ ‘; 可能得循环几千次才会判断到,所以为了更即时的检测到状态你必须每次循环时输出足够多的内容才会触发状态检测。

所以这里也经常会遇到一个问题:当浏览器断开后,即使没有使用 ignore_user_abort(true); 但因为没有任何输出,导致程序仍然会继续执行,死循环会一直跑,如果设置了超时那还好,否则就真死掉了。


下面贴上测试代码(贴个图主要是为了防盗 嘿嘿~)

set_time_limit(0);

ignore_user_abort(true);

while (1) {
    echo str_repeat(' ', 65536);
    $isAborted = connection_aborted();
    $status = connection_status();
    file_put_contents('test.txt', 'time: '. time() .'; abroted:'. $isAborted .'; status: '. $status);
    if (0 !== $status  $isAborted) {
        break;
    }
    sleep(2);
}

你可以试试注释掉这句
// echo str_repeat(’ ‘, 65536);
另外
set_time_limit(0); 最好也别用 0

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索问题
, nginx
, 程序
, status
, 输出
, nginx svn htt协议
, ignore_user_abort
, ignore_user_abort函数
, ignore_user_abort例子
str_repeat函数
connection close、but connection close、connection 直接close、nginx connection、urlconnection close,以便于您获取更多的相关知识。

时间: 2024-10-03 18:44:53

PHP 在 Nginx 下主动断开连接 Connection Close 与 ignore的相关文章

PHP 在 Nginx 下主动断开连接 Connection Close 与 ignore_user_abort 后台运行

这两天弄个PHP调用 SVN 同步 update 多台服务器更新的程序,为了避免 commit 的时候不会被阻塞卡半天得想个办法只请求触发,而不需要等待程序 update 完成返回结果这样耗时太长,所以研究过了下如何让PHP主动断开连接的方法.搞了一下午,发现很多问题,还好最终还是弄出来了,主要是 Nginx 太坑.. 废话不多说,下面上代码: /** * 主动断开与客户端浏览器的连接 * 如果是 Nginx 服务器需要输出大于等于 fastcgi_buffer_size 缓存的数据才能即时输出

[求助] socket通信.客户端怎样主动断开连接.

问题描述 如题,客户端怎样主动强制和服务器断开,调用socket.close()后服务器inputstream.read()无限循环得到空字符串服务器部分代码:privatevoidsocket(){ServerSocketss;try{ss=newServerSocket(9988);//等待连接客户端System.out.println("正在侦听");Sockets=ss.accept();System.out.println("-----------连接成功-----

tcp-求网络大牛解决疑难杂症,为何断开连接后,不出现time_wait状态

问题描述 求网络大牛解决疑难杂症,为何断开连接后,不出现time_wait状态 我们都知道,tcp/ip协议断开连接是4次挥手,主动断开的一方,最后会进入time_wait状态,等待2MSL后变成CLOSED,但是我在本地做了一个php网页,代码逻辑就是先sleep,3秒钟然后输出几个字符,但是查看网络状态时,压根找不到time_wait的状态: 以下是通过natstat命令,查看到机器上的状态 1.在服务器sleep的时候,建立连接的双方都是ESTABLISHED 2.网页输出之后,大约过3秒

Linux 下配置nginx到php的连接

在中小企业中,LAMP架构被广泛使用.而对于高并发请求的情形,其Web服务器通常以Nginx居多,因此LNMP组合架构也非常普遍.在LAMP架构中,Apache可以使用三种方式与PHP连接通信,即以模块化的方式,CGI(已不再使用)以及FastCGI.那对于Nginx而言,则可以使用FastCGI方式,即反向代理方式,将PHP代码有FastCGI转交给PHP解释器进行处理.本文描述配置Nginx到PHP的连接. 一.环境准备 安装Nginx:Linux 6 下安装编译安装Nginx 安装PHP

HTTP 499 状态码 nginx下 499错误的解决办法_nginx

日志记录中HTTP状态码出现499错误有多种情况,我遇到的一种情况是nginx反代到一个永远打不开的后端,就这样了,日志状态记录是499.发送字节数是0. 老是有用户反映网站系统时好时坏,因为线上的产品很长时间没有修改,所以前端程序的问题基本上可以排除,于是就想着是Get方式调用的接口不稳定,问了相关人员,说没有问题,为了拿到确切证据,于是我问相关人员要了nginx服务器的日志文件(awstats日志),分析后发现日志中很多错误码为499的错误,约占整个日志文件的1%,而它只占全部报错的70%左

WebSocket(伍) 断开连接

原文链接 https://www.web-tinker.com/article/20310.html WebSocket是很民主的,啥都要协商!建立连接时需要握手协议,连断开连接都需要双方共同完成!其实断开连接直接断开TCP连接就可以了,但是这有点暴力.文明点的方法是发个请求,让对方自己断开.客户端要主动断开就必须向服务器发送8这个操作码. 首先是服务器主导断开的情况,最简单的方法是直接把TCP连接断开,这里就不演示了.由于这对客户端来说是个意外断开,WebSocket对象采取应急措施也触发cl

qt-使用QT,主机做了一个服务端,局域网中可以连接别人,别人连接自己输入字符就会断开连接

问题描述 使用QT,主机做了一个服务端,局域网中可以连接别人,别人连接自己输入字符就会断开连接 5C cmd下使用telnet也是输入字符就断开连接电脑杀毒软件一直没启动,防火墙全部关闭,端口号10000然后写了个客户端,同样的问题,输入字符断开连接.楼下依次上图 解决方案 解决方案二: 解决方案三: 解决方案四: 解决方案五: 输入字符a就出现了断开连接 下面上代码 解决方案六: chatsever.h #ifndef CHATSEVER_H#define CHATSEVER_H #inclu

将数据访问页绑定到断开连接的记录集

断开|访问|记录集|数据 Meyyammai SubramanianMicrosoft Corporation 2001 年 4 月 适用于:Microsoft Access 2002 摘要:本文说明如何将数据访问页绑定到断开连接的 ADO 记录集. 目录简介创建使用断开连接的记录集的数据访问页 简介断开连接的记录集是客户端高速缓存中的对象,该对象没有同服务器实时连接.使用断开连接的记录集,ActiveX 数据对象 (ADO) 允许您创建记录集,断开与数据源的连接,使用户可以脱机查看和编辑记录集

TCP断开连接过程详解

上次我们讲了TCP三次握手建立连接的过程,今天我们结合双方状态的改变来讲讲TCP断开连接的过程:TCP四次挥手. 数据传输结束后,通信的双方都可释放连接.现在A和B都处于ESTABLISHED状态.A的应用程序先向TCP发出连接释放报文段,主动关闭TCP连接.A把连接释放报文段的首部FIN置为1,序号seq=u,它等于前面已传送过的数据的最后一个字节的序号加1.这时A进入FIN-WAIT-1状态,等待B的确认. B收到连接释放报文段后即发出确认,确认号是ack=u+1,而这个报文段自己的序号是v