必须禁用Nginx缓冲、关闭缓存、启用HTTP/1.1、清除Connection头、延长读写超时至24小时,并配合PHP脚本关闭输出缓冲、发送SSE头与心跳,Windows下还需启用tcp_nodelay并控制推送粒度。

phpEnv里Nginx默认不支持SSE长连接
phpEnv自带的Nginx配置是面向传统PHP-FPM动态请求的,完全没考虑SSE场景。它默认开启proxy_buffering、启用缓存、使用HTTP/1.0兼容逻辑,这些都会直接截断SSE流——你看到的“一口气返回全部数据”或“连接几秒就断”,根本不是后端问题,而是Nginx在中间把流吃掉了。
必须改location块里的关键代理参数
假设你的SSE接口路径是/api/events,后端跑在http://127.0.0.1:8080(比如用PHP内置服务器或Spring Boot),需要在phpEnv的Nginx配置文件(通常是C:\phpEnv\nginx\conf\vhosts\your-site.conf)中,对应location块里加这几行:
-
proxy_buffering off:禁用缓冲,否则Nginx攒够一整块才发,SSE实时性全毁 -
proxy_cache off:SSE响应不可缓存,否则第一次之后全是旧数据 -
proxy_http_version 1.1:HTTP/1.0不支持持久连接,SSE直接失效 -
proxy_set_header Connection '':清空Connection头,避免被转成close -
proxy_read_timeout 86400和proxy_send_timeout 86400:超时设成24小时,适应SSE空闲期 -
proxy_hide_header X-Accel-Buffering+add_header X-Accel-Buffering no:防止Nginx自作主张开缓冲(尤其Windows下常见)
别碰proxy_set_header Upgrade和Connection 'upgrade'——那是WebSocket用的,SSE不需要,加了反而可能干扰。
后端PHP脚本要手动发SSE头和心跳
phpEnv里跑PHP脚本做SSE,光配Nginx不够。PHP本身会默认开启输出缓冲,你得在脚本开头强制关掉:
立即学习“PHP免费学习笔记(深入)”;
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('X-Accel-Buffering: no');
ob_end_clean(); // 关掉PHP自身的输出缓冲
flush();
然后必须定期输出合法SSE格式,比如每15秒发个注释心跳:
echo ": heartbeat\n\n"; ob_flush(); flush();
漏掉ob_flush()和flush(),数据卡在PHP层出不来;不加心跳,Nginx或浏览器可能因空闲超时主动断连。
Windows下phpEnv特有的坑:Send-Q堆积和内存暴涨
在phpEnv这种Windows集成环境里跑SSE长连接,容易遇到Nginx worker进程Send-Q堆积(ss -nt能看到Send-Q几百KB往上飙),接着内存缓慢上涨,最后worker被系统OOM kill。这不是配置错,而是Windows TCP栈对长连接空闲数据包处理不如Linux稳定。
缓解方法只有两个:
- 后端必须严格控制单次输出大小(别一次echo几MB),用小块+高频心跳代替大块推送
- 在Nginx配置里加
tcp_nodelay on,减少Nagle算法带来的微小延迟合并
这个点很容易被忽略:你以为配对了就能稳,其实Windows环境下SSE的稳定性高度依赖后端推送节奏和数据粒度。



















