workerman通过nginx反向代理实现websocket推送时,必须配置proxy_set_header host $host、x-real-ip $remote_addr、x-forwarded-for $proxy_add_x_forwarded_for、proxy_http_version 1.1及upgrade/connection头,并设超时为180秒、关闭proxy_buffering,https需透传x-forwarded-proto以确保连接不中断、ip真实、消息精准触达。

Workerman主动推送信息时,若前端通过Nginx反向代理访问,必须确保WebSocket连接不被中断、客户端真实IP可识别、消息能精准触达目标用户,否则会出现推送失败、用户收不到、日志IP全为127.0.0.1等问题。
Nginx必须透传关键Header和升级头
第一步:在location块中添加proxy_set_header Host $host;否则Workerman内部生成的URL(如ws://your.com/ws)会 fallback 成 ws://127.0.0.1:2346,前端无法建立连接。
第二步:必须设置proxy_set_header X-Real-IP $remote_addr 和 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;否则request()->ip()始终返回127.0.0.1,导致按IP限频、地域判断、用户绑定全部失效。
第三步:WebSocket场景下,【proxy_http_version 1.1、Upgrade、Connection三者缺一不可】。漏掉任意一个,Nginx会以HTTP/1.0响应,直接拒绝协议升级,客户端报错“Error during WebSocket handshake: Unexpected response code: 200”。
超时与缓冲配置直接影响推送稳定性
proxy_connect_timeout、proxy_send_timeout、proxy_read_timeout全部设为180秒;默认60秒会在长轮询或大消息推送中途断开,触发502 Bad Gateway。
proxy_buffering off;Workerman本身已做流式响应,Nginx开启缓冲会导致SSE/Stream响应卡住、WebSocket粘包,新消息延迟数秒才到达前端。
注意:proxy_buffering一旦开启,即使Workerman flush()也无效,前端必须等缓冲区满或超时才收到数据。
HTTPS与WSS必须由Nginx终止并透传协议标识
方法一:Nginx监听443端口,配置ssl_certificate与ssl_certificate_key,同时添加proxy_set_header X-Forwarded-Proto $scheme;否则Workerman中$request->isSecure()恒为false,wss://链接会被降级为ws://,浏览器直接拦截。
方法二:强制跳转HTTPS——在80端口server块内加return 301 https://$host$request_uri;避免用户手动输http://导致WSS握手失败。
这一步操作起来很简单,直接把证书文件路径填进配置就行,但漏配X-Forwarded-Proto会导致所有安全校验逻辑误判。
灰度推送时Nginx upstream权重需动态调整
① 启动新版本Workerman监听端口2829,旧版保持2828;
② 在upstream中定义两组后端:
upstream ws_backend {
server 127.0.0.1:2828 weight=90;
server 127.0.0.1:2829 weight=10;
}
③ location /ws { proxy_pass http://ws_backend; };
【nginx -s reload后权重立即生效,但已有WebSocket连接不会迁移】——这意味着灰度期间新连接走新版本,老连接仍留在旧版本,推送需双写或等待自然断连。











