Workerman 的 WebSocket 服务需由 Nginx 正确代理:必须启用 HTTP/1.1、透传 Upgrade 和 Connection 头,路径严格匹配,WSS 由 Nginx 终止 TLS,Workerman 仅监听 127.0.0.1 并使用明文 ws:// 转发。

Workerman 的 WebSocket 服务不能直接被 Nginx 转发到 http:// 协议
因为 Nginx 默认只代理 HTTP/HTTPS 流量,而 WebSocket 建立连接时依赖 Upgrade: websocket 和 Connection: Upgrade 这两个关键头;如果 Nginx 没配对,请求会卡在 400 或直接断开。
- 典型错误现象:
WebSocket connection to 'wss://xxx' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED或浏览器控制台报failed: Error during WebSocket handshake: Unexpected response code: 400 - 必须显式开启
proxy_http_version 1.1,否则 Nginx 用 HTTP/1.0 转发,压根不传Upgrade头 -
proxy_set_header Upgrade $http_upgrade和proxy_set_header Connection "upgrade"缺一不可——前者把客户端的升级意图透传,后者告诉 Nginx 自己要升为 WebSocket 连接
Nginx 配置里 location /ws/ 必须和 Workerman 监听路径严格一致
Workerman 的 WebSocket Server 是纯 TCP 服务,不解析 URL 路径;但 Nginx 的 location 匹配决定了哪些请求能走到 WebSocket 后端。路径不匹配,Nginx 就不会走你写的 WebSocket 代理块,而是 fallback 到其他规则(比如静态文件或 PHP)。
- 常见错误:Workerman 启动在
ws://127.0.0.1:2346,前端连的是wss://domain.com/realtime,但 Nginx 只写了location /ws/,结果请求根本没进这个 block - 建议统一用
location /+ 前端指定完整路径,或明确约定一个前缀(如/ws/),并在 JS 中 new WebSocket('wss://domain.com/ws/') - 注意:Nginx 的
proxy_pass末尾加不加/会影响路径重写——proxy_pass http://127.0.0.1:2346/;会剥离/ws/再转发,而proxy_pass http://127.0.0.1:2346;会原样转发,Workerman 端需自己处理路径
WSS(加密 WebSocket)必须由 Nginx 终止 TLS,Workerman 不处理证书
Workerman 本身不支持 SSL/TLS,所有 wss:// 请求必须由 Nginx 解密后再以明文 ws:// 转发给 Workerman。强行让 Workerman 自己监听 443 或加载证书,只会导致握手失败或性能异常。
- 错误做法:在 Workerman 代码里调用
ssl://或尝试读取server.pem——它不是 Web 服务器,没内置 OpenSSL 支持 - 正确链路:
浏览器 wss:// → Nginx(解密)→ 明文 ws://127.0.0.1:2346 - Nginx 配置中必须包含
ssl_certificate和ssl_certificate_key,且域名与证书一致;否则浏览器会报net::ERR_CERT_AUTHORITY_INVALID - 如果本地测试想绕过 HTTPS,可用
ws://+ HTTP 端口,但生产环境必须用 WSS,否则现代浏览器会直接屏蔽未加密的 WebSocket
Workerman 进程必须监听 127.0.0.1 而非 0.0.0.0(安全与调试角度)
虽然 0.0.0.0:2346 能让外部直连,但这样等于把 WebSocket 端口暴露在公网,跳过了 Nginx 的限流、日志、TLS、IP 白名单等能力,也容易被扫描工具探测并发起恶意连接。
- Workerman 启动时应绑定
127.0.0.1:2346,确保只有本机 Nginx 能访问 - 检查是否生效:运行
netstat -tuln | grep :2346,输出应为tcp 0 0 127.0.0.1:2346 0.0.0.0:* LISTEN,而非*:2346 - 如果用了 Docker,注意容器内网 IP 和宿主机网络模式——
127.0.0.1在容器里指容器自身,此时 Nginx 若在宿主机,得用宿主机 IP 或host.docker.internal(Mac/Win)或自定义 bridge 网络
Nginx 的 proxy_read_timeout 很容易被忽略,默认 60 秒,WebSocket 长连接若空闲超时,Nginx 会主动断开,前端收到 close event。设成 0 表示不限制,但得配合 Workerman 心跳逻辑一起看。










