php实时输出配合sse怎么做_php实时输出sse推送教程【教程】

发布时间 - 2026-01-29 00:00:00    点击率:
PHP输出缓冲必须关闭,否则SSE无法实时推送;需设置正确响应头、严格遵循消息格式、处理连接断开与重连,并防止Web服务器及PHP-FPM中间层缓存。

PHP 输出缓冲必须关掉,否则 SSE 不会实时

SSE(Server-Sent Events)依赖服务端持续写入响应流,而 PHP 默认开启输出缓冲(output_buffering),会导致数据攒在缓冲区里不发出去。不关它,前端永远收不到第一条消息。

实操建议:

  • 脚本开头加 ob_end_flush()ob_flush(),再调用 flush();更稳妥的做法是直接禁用:ini_set('output_buffering', 'Off')ini_set('zlib.output_compression', 'Off')
  • Apache 下还要确认 mod_deflate 没对 SSE 响应做压缩(它会拦截并缓存响应),Nginx 则需关掉 gzip 或用 gzip off; 针对 SSE 路由
  • 如果用了 PHP-FPM,buffer_size 设为 0(或 0s)避免 FPM 层缓存

header 设置不能错,Content-Type 和 Cache-Control 是关键

SSE 要求响应头严格符合规范,漏掉或写错一个,浏览器就当普通 HTTP 响应处理,不会建立 EventSource 连接。

必须设置的 header:

  • header('Content-Type: text/event-stream') —— 类型错成 application/json 或漏掉,连接直接失败
  • header('Cache-Control: no-cache') —— 浏览器可能缓存初始响应,后续推送全失效
  • header('Connection: keep-alive') —— 显式声明长连接,避免代理/CDN 中断
  • 可选但推荐:header('X-Accel-Buffering: no')(Nginx)防止其内部缓冲

每条消息必须以 data: 开头,结尾用双换行

SSE 协议规定消息格式极其简单,但容错极低:字段名必须小写,冒号后要空格,每条消息末尾必须是两个 \n(即 \n\n)。少一个换行,浏览器就卡住不解析。

正确示例:

data: {"status":"ok","time":1716234567}

data: hello

常见错误:

  • echo "event: ping\ndata: alive\n\n" 却忘了 echo 默认不带换行,得手动补 \n
  • JSON 字符串里混入 HTML 实体或未转义双引号,导致前端 JSON.parse() 报错
  • 循环中没控制频率,高频 echo + flush() 可能触发 Apache 的 TimeOut 或 Nginx 的 proxy_read_timeout

客户端 EventSource 连接断开后,重连逻辑得自己管

PHP 无法主动感知客户端断开(除非用心跳+超时检测

),而浏览器 EventSource 在网络抖动或服务重启后会自动重连——但它只按固定规则重试(首次延迟 ~5s,之后指数退避),且不会传 cookie 或自定义 header。

实际要注意的点:

  • 后端别假设连接永久存在,每次 echo 前先检查 connection_status() === CONNECTION_NORMAL,否则可能向已断连接写数据,触发警告甚至进程终止
  • 需要鉴权?别依赖 session cookie(重连时不发),改用 URL 参数传 token,或前端初始化时先 fetch 一次获取临时凭证
  • 若需保证消息不丢,服务端得维护游标(如 last_id),客户端重连时带上上次收到的 ID,服务端从该位置继续推
SSE 看似简单,真正跑稳的关键不在“怎么发”,而在“怎么不让它被中间层吞掉”和“怎么扛住连接反复断”。很多问题不是代码写错了,而是 Apache/Nginx/PHP-FPM 的默认缓冲策略在背后悄悄改写了你的响应流。


# php  # html  # js  # 前端  # json  # apache  # nginx  # cookie  # 浏览器  # app  # session  # 后端  # echo 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: INTERNET浏览器怎样恢复关闭标签页_INTERNET浏览器标签恢复快捷键与方法【指南】  做企业网站制作流程,企业网站制作基本流程有哪些?  如何快速搭建FTP站点实现文件共享?  如何在IIS管理器中快速创建并配置网站?  如何用花生壳三步快速搭建专属网站?  网站制作软件有哪些,制图软件有哪些?  jQuery validate插件功能与用法详解  Win11任务栏卡死怎么办 Windows11任务栏无反应解决方法【教程】  Swift中switch语句区间和元组模式匹配  怎样使用JSON进行数据交换_它有什么限制  Laravel如何使用Guzzle调用外部接口_Laravel发起HTTP请求与JSON数据解析【详解】  Laravel如何保护应用免受CSRF攻击?(原理和示例)  教你用AI将一段旋律扩展成一首完整的曲子  西安专业网站制作公司有哪些,陕西省建行官方网站?  Thinkphp 中 distinct 的用法解析  微信小程序 五星评分(包括半颗星评分)实例代码  如何选择可靠的免备案建站服务器?  Laravel怎么使用Intervention Image库处理图片上传和缩放  香港服务器网站生成指南:免费资源整合与高速稳定配置方案  奇安信“盘古石”团队突破 iOS 26.1 提权  Laravel如何使用Livewire构建动态组件?(入门代码)  油猴 教程,油猴搜脚本为什么会网页无法显示?  香港服务器租用费用高吗?如何避免常见误区?  使用spring连接及操作mongodb3.0实例  JavaScript 输出显示内容(document.write、alert、innerHTML、console.log)  Laravel怎么定时执行任务_Laravel任务调度器Schedule配置与Cron设置【教程】  深圳网站制作设计招聘,关于服装设计的流行趋势,哪里的资料比较全面?  php结合redis实现高并发下的抢购、秒杀功能的实例  Laravel怎么实现前端Toast弹窗提示_Laravel Session闪存数据Flash传递给前端【方法】  Gemini怎么用新功能实时问答_Gemini实时问答使用【步骤】  如何用景安虚拟主机手机版绑定域名建站?  iOS UIView常见属性方法小结  Win11搜索栏无法输入_解决Win11开始菜单搜索没反应问题【技巧】  Laravel路由Route怎么设置_Laravel基础路由定义与参数传递规则【详解】  Laravel如何使用Vite进行前端资源打包?(配置示例)  ,南京靠谱的征婚网站?  如何在局域网内绑定自建网站域名?  如何用wdcp快速搭建高效网站?  Laravel如何处理JSON字段_Eloquent原生JSON字段类型操作教程  python中快速进行多个字符替换的方法小结  Laravel辅助函数有哪些_Laravel Helpers常用助手函数大全  如何在云主机上快速搭建多站点网站?  Laravel怎么集成Vue.js_Laravel Mix配置Vue开发环境  ChatGPT回答中断怎么办 引导AI继续输出完整内容的方法  Google浏览器为什么这么卡 Google浏览器提速优化设置步骤【方法】  Windows家庭版如何开启组策略(gpedit.msc)?(安装方法)  Laravel项目怎么部署到Linux_Laravel Nginx配置详解  常州企业网站制作公司,全国继续教育网怎么登录?  iOS正则表达式验证手机号、邮箱、身份证号等  惠州网站建设制作推广,惠州市华视达文化传媒有限公司怎么样?