You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 8生产环境使用Server Sent Event报ob_flush无缓冲区可刷新错误

错误原因
  • 本地开发环境PHP默认开启output_buffering配置,存在活跃输出缓冲区,调用ob_flush()可正常执行
  • 生产环境通常会关闭默认输出缓冲,或Symfony StreamedResponse内部已提前处理缓冲逻辑,此时直接调用ob_flush()无缓冲区可刷新,就会抛出该错误
  • 原有代码还存在两处隐含问题:响应头Cach-Control拼写错误(少了字母t)、SSE消息未遵循data: 前缀规范,会导致前端无法正常接收事件
修复代码

直接替换原有逻辑即可:

public function notificationsCount(Request $request)
{
    try {
        $response = new \Symfony\Component\HttpFoundation\StreamedResponse(function () use ($request) {
            // 手动开启输出缓冲区,兼容不同环境配置
            ob_start();
            while (true) {
                $notif_count = Auth::user()->unreadNotifications->count();
                // 遵循SSE格式要求,添加data前缀
                echo "data: " . json_encode(['data' => $notif_count]) . "\n\n";
                // 先判断是否存在活跃缓冲区再刷新
                if (ob_get_level() > 0) {
                    ob_flush();
                }
                flush();
                sleep(1);

                if (connection_aborted()) {
                    break;
                }
            }
            if (ob_get_level() > 0) {
                ob_end_flush();
            }
        });
        $response->headers->set('Content-Type', 'text/event-stream');
        $response->headers->set('X-Accel-Buffering', 'no');
        // 修复响应头拼写错误
        $response->headers->set('Cache-Control', 'no-cache');
        // Laravel中无需手动调用send(),直接返回响应对象即可
        return $response;
    } catch (\Exception $e) {
        return response()->json(['error' => $e->getMessage()]);
    }
}
额外生产环境检查项
  • 确认Nginx/Apache等Web服务器未开启text/event-stream类型响应的gzip压缩,压缩会导致缓冲无法实时刷新
  • 若使用CDN,需配置SSE接口的缓存规则为不缓存,避免CDN缓冲响应内容

内容的提问来源于stack exchange,提问作者Ausaf Liaquat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 21:06:02