PHP 在 Nginx 下主动断开连接 Connection Close 与 ignore_user_abort 后台运行
来源:互联网 发布:知无涯者评价 编辑:程序博客网 时间:2024/04/25 05:12
这两天弄个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 null|string $str 当前输出的内容, 若无需输出则设置为空 */public function connectionClose($str = null) { $str = ob_get_contents() . $str; // 若实际输出内容长度小于该值将可能导致主动断开失败 header('Content-Length: '. strlen($str)); header('Connection: Close'); 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
- PHP 在 Nginx 下主动断开连接 Connection Close 与 ignore_user_abort 后台运行
- PHP主动断开与浏览器的连接
- PHP主动断开与浏览器的连接
- 服务器主动断开连接异常
- php ignore_user_abort()实现计划任务功能,实现文件能够在浏览器关掉之后照样运行
- Nginx主动连接与被动连接的区别
- 判断客户端是否主动断开连接
- CC2540 BLE peripheral 主动断开连接
- window下redis的连接与断开
- Windows RunHiddenConsole 后台运行 nginx,php,redis
- tcp的关闭(shutdonw、close、SO_LINGER选项)与 连接断开情形判断
- Nginx在Linux下的安装与运行
- PHP ignore_user_abort() 函数
- PHP ignore_user_abort() 函数
- PHP 函数ignore_user_abort ()
- 在Nginx下运行thinkphp
- php与nginx的连接
- Unix/Linux中后台运行程序(断开shell连接后继续执行)的几种方式
- C语言之函数调用01—1到n的阶乘和
- 当以太网碰上NVMe
- oracle数据库--Oracle双引号和单引号的区别小结
- c++
- VNC Keyboard Remote Code Execution
- PHP 在 Nginx 下主动断开连接 Connection Close 与 ignore_user_abort 后台运行
- GNU Linux高并发性能优化方案
- “黑马程序员” GUI 图形用户界面
- C语言之函数调用02—一个三位数的正整数=它的各位数字的阶乘之和
- IT程序员必备开发手册
- tcp_tw_recycle检查tcp_timestamps的内核代码
- oracle数据库--Oracle 左连接、右连接、全外连接、(+)号作用
- C语言之函数调用03—最大公约数和最小公倍数
- onSaveInstanceState的初步使用