Laravel 请求接口接收流式响应,并以流式响应返回给用户

Laravel ⋅ tytrock ⋅ at 2025-12-13 17:23:14 ⋅ 1503 Reads

1、请求外部接口接收流式响应

Laravel 的Http门面基于 Guzzle 实现,支持流式响应处理(通过stream()方法或注册进度 / 回调函数)。

use Illuminate\Support\Facades\Http;

// 请求外部流式接口,逐块处理数据
$response = Http::withOptions([
    'stream' => true, // 开启流式处理(关键)
    'timeout' => 0,   // 禁用超时(若流式响应耗时较长)
])->post('http://192.168.1.107/test',['name'=>'张三']); // 外部流式接口地址,POST方式
//])->get('http://192.168.1.107/test'); // 外部流式接口地址,GET方式


2、Laravel以流式响应返回给用户

// 设置SSE响应头(关键:保持连接、分块传输)
$headers = [
    'Content-Type' => 'text/event-stream',
    'Cache-Control' => 'no-cache',
    'Connection' => 'keep-alive',
    'X-Accel-Buffering' => 'no', // 禁用Nginx缓冲(重要,否则会被缓存后一次性输出)
];
// 返回流式响应
if ($response->successful()) {
    return response()->stream(function () use ($response) {
        $stream = $response->getBody();
        $bufferSize = 10;//缓存区大小,数值越大每次返回的数据就越多,但每次响应时间会较长
        while (!$stream->eof()) {
            echo $stream->read($bufferSize);
            ob_flush();
            flush();
        }
        echo "data: [DONE]\n\n";
        ob_flush();
        flush();
    }, 200, $headers);
}else{
    return '请求失败';
}


附自行制作流式响应

// 设置SSE响应头(关键:保持连接、分块传输)
$headers = [
    'Content-Type' => 'text/event-stream',
    'Cache-Control' => 'no-cache',
    'Connection' => 'keep-alive',
    'X-Accel-Buffering' => 'no', // 禁用Nginx缓冲(重要,否则会被缓存后一次性输出)
];

// 返回流式响应
return response()->stream(function () {
    // 模拟分块输出数据(实际场景可替换为数据库查询、文件读取、任务执行等)
    for ($i = 1; $i <= 5; $i++) {
        // SSE数据格式:data: 内容\n\n(必须遵循该格式)
        echo "data: 第{$i}条流式数据:" . date('Y-m-d H:i:s') . "\n\n";
        ob_flush(); // 刷新输出缓冲区
        flush();    // 强制输出到客户端
        sleep(1);   // 模拟耗时操作(每秒输出一条)
    }
    // 结束流(可选)
    echo "data: [DONE]\n\n";
    ob_flush();
    flush();
}, 200, $headers);


注意事项:

  • 禁用缓冲:添加X-Accel-Buffering: no头,防止 Nginx/Apache 将响应缓存后一次性输出。

  • SSE 格式:必须以data: 内容\n\n为单位输出,否则前端 EventSource 无法识别。

  • 长连接:SSE 会保持连接直到服务端关闭,若需主动关闭,可在前端调用eventSource.close()。


This topic has been mark as Excenllent Topic.
Total Reply Count: 0
    No comments~~
    • publish_typography
    • publish_markdown
    • 支持表情,使用方法请见 Emoji 自动补全来咯,可用的 Emoji 请见 :metal: :point_right: Emoji 列表 :star: :sparkles:
    • publish_image
    • publish_draft
    Ctrl+Enter