workerman 4 http 流式输出需手动启用 chunked 编码:设置 transfer-encoding: chunked、清除 content-length、用 write() 分批发送,禁用输出缓冲及 nginx 缓冲,注意客户端兼容性与超时配置。

Workerman 4 的 HTTP 服务默认不启用 chunked 编码,要实现流式输出大文本(如日志、导出 CSV、实时日志推送等),需手动设置响应头并控制输出节奏。
启用 Transfer-Encoding: chunked
Workerman 的 Worker::$output 默认使用 Content-Length,必须显式禁用它,并添加 Transfer-Encoding: chunked 响应头。注意:不能同时存在 Content-Length 和 chunked,否则客户端会解析失败。
- 调用
$response->header('Transfer-Encoding', 'chunked') - 确保未设置
Content-Length(Workerman 4 通常不会自动加,但若手动设过需清除) - 关闭输出缓冲:
$response->end()不可用,改用$response->write()分批发送
使用 write() 分块写入内容
$response->write($data) 会立即发送一段数据(含 chunk 头尾),适合逐行或按固定大小(如 8KB)推送。每调用一次,就生成一个 chunk;多次调用即构成流式响应。
- 每次
write()的数据建议控制在 4KB–64KB,避免小包过多或内存积压 - 如输出大文件,可用
fopen + fread循环读取并write(),不加载全文到内存 - 末尾无需额外操作,连接关闭时自动结束 chunked 流(也可显式
$response->end('')补零长度 chunk)
避免常见陷阱
Chunked 流式响应对客户端兼容性敏感,以下问题高频出现:
-
NGINX 中间代理会缓冲 chunked 响应:需配置
proxy_buffering off;和chunked_transfer_encoding on; -
浏览器 DevTools 可能延迟渲染流式文本:建议加换行符或 HTML 换行(
<br>)提升可读性 -
PHP 输出控制函数干扰:禁用
ob_start()、ob_flush()等,Workerman 自主管理底层 socket -
连接超时中断流:客户端或反向代理(如 Nginx 的
proxy_read_timeout)需延长超时时间
简易示例:逐行输出 10 万行文本
以下代码在 Workerman 4 HTTP 路由中运行,模拟实时日志流:
$router->get('/stream-log', function ($request, $response) {
$response->header('Content-Type', 'text/plain; charset=utf-8');
$response->header('Transfer-Encoding', 'chunked');
$response->header('X-Content-Type-Options', 'nosniff');
for ($i = 1; $i write($line);
// 可选:每 100 行微休眠,避免压垮客户端
if ($i % 100 === 0) {
usleep(1000); // 1ms
}
}
});











