frankenphp通过mercure实现sse推送,兼容性取决于浏览器eventsource支持:chrome/edge/firefox完整支持,safari需16.4+,旧版ios/android需降级方案;配置需https、调优caddy超时、禁用php输出缓冲,并显式设置publish_origins与cors。

FrankenPHP的SSE推送在主流浏览器里基本能用,但有细节差异
FrankenPHP本身不直接提供SSE(Server-Sent Events)协议层,它通过内置的 Mercure 协议实现服务端主动推送,而 Mercure 的客户端默认使用 SSE 作为传输机制。这意味着浏览器兼容性本质上取决于其对 EventSource API 的支持程度,而非 FrankenPHP 自身实现。
Chrome、Edge、Firefox 支持完整,Safari 从 16.4 开始才稳定支持 EventSource
常见问题不是“能不能连”,而是连接建立后是否能持续接收事件:
- Chrome / Edge(Chromium 内核):完全支持
EventSource,包括重连逻辑、自定义事件类型、last-event-id恢复,无需 polyfill - Firefox:同样完整支持,且对长连接空闲超时更宽容
- Safari:iOS 16.4+ 和 macOS Ventura 13.3+ 才修复了
EventSource在后台标签页中被静默终止的问题;旧版本(如 Safari 15.x)会频繁断连且不触发onerror - Android WebView(基于 Chromium):一般没问题,但需确认系统 WebView 版本 ≥ 90
FrankenPHP 的 Mercure 配置会影响实际表现
即使浏览器支持 SSE,如果后端配置不当,前端仍会表现为“连接秒断”或“收不到事件”。关键点包括:
-
Mercure.publish_url和Mercure.subscribe_url必须使用 HTTPS(本地开发可用https://localhost,Caddy 会自动签发证书) - Caddy 的
timeout_idle和timeout_read默认值偏保守,建议在 Caddyfile 中显式延长:mercure { publish_origins https://your-app.com timeout_idle 300s timeout_read 300s } - PHP 应用若启用了
output_buffering或调用了ob_end_flush(),可能提前关闭响应流,导致 SSE 连接中断 - 不要在 PHP 脚本中写
header('Content-Type: text/event-stream')—— Mercure 的 Hub 已接管响应头,手动设置会冲突
移动端和低版本环境需要 fallback 策略
如果你的应用必须覆盖 iOS 15 或 Android 8 以下设备,纯 SSE 就不够可靠。这时得考虑:
- 用 Mercure 的
polyfill(官方提供)降级到轮询,但会失去实时性 - 在关键业务路径(如订单状态变更)加一次 HTTP 轮询兜底,避免用户卡在“加载中”
- 避免依赖
EventSource的retry字段做业务逻辑判断,不同浏览器对该字段的实际处理不一致
真正容易被忽略的是:FrankenPHP 的 Mercure Hub 默认只允许本地订阅,上线前必须显式配置 publish_origins 和 CORS 头,否则 Safari 和部分 Android 浏览器会因预检失败直接拒绝连接。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











