Laravel长耗时API端点如何检测客户端HTTP连接是否仍存活
Laravel长耗时端点客户端连接检测实现方案
实现原理
PHP原生提供了客户端连接状态检测能力,无需依赖异步队列或者WebSocket即可实现需求:
- PHP内置
connection_aborted()函数可检测客户端连接状态,返回1表示连接已断开,0表示仍正常连接 - 需配合
ignore_user_abort(false)配置使用:该配置开启后,客户端断开连接时PHP会终止脚本执行,部分环境默认该值为true,即使客户端断开脚本也会继续运行 - 注意:
connection_aborted()的状态只会在PHP尝试向客户端发送输出时更新,若全程无输出状态不会实时刷新
具体实现代码
你可以直接按照如下方式改造你的端点逻辑:
function myAPIEndpoint($all_batches){ // 关闭忽略用户断开的默认行为,连接断开后触发脚本终止逻辑 ignore_user_abort(false); $result = []; foreach ($all_batches as $batch) { $batch_result = do_something_long($batch); $result = array_merge($result, $batch_result); // 每批次处理完成后检测连接状态 $this->checkIfClientIsStillConnected(); } // 清空处理过程中输出的空字符,避免影响最终响应 ob_clean(); return response()->json($result); } private function checkIfClientIsStillConnected() { // 输出极小的空字符,触发连接状态更新 echo "\0"; // 强制清空输出缓冲,将内容发送到客户端侧 ob_flush(); flush(); // 连接已断开则抛出异常终止处理 if (connection_aborted()) { throw new \RuntimeException('客户端连接已断开,终止批量处理'); } }
常见环境适配
- 若使用Nginx作为反向代理,确保Nginx配置中
proxy_ignore_client_abort为off(默认值),此时客户端断开连接后Nginx会主动关闭与PHP-FPM的连接,PHP可以正常检测到状态变化 - 若批量处理逻辑中存在超过Nginx
proxy_read_timeout时长的阻塞操作(比如超长SQL查询),需要调整该超时阈值,避免Nginx主动断开连接导致误判 - 如果业务不允许在处理过程中输出任何内容,也可以将检测逻辑替换为调用
connection_status()函数判断状态,效果一致
内容的提问来源于stack exchange,提问作者Robycool
相关产品推荐
相关产品推荐

