workerman 不能直接处理 wss,必须由 nginx 反向代理完成 tls 终结和 websocket 协议升级;因其仅工作在 tcp 层,不解析 tls/sni/证书链,硬启 ssl:// 会导致连接被拒或 400 错误。

Workerman 不能直接绑定域名或处理 WSS,必须靠 Nginx 反向代理完成 TLS 终结和 WebSocket 协议升级——这是唯一稳定、微信小程序能连上的方案。
为什么 Workerman 自己监听 443 + SSL 会失败
Workerman 的 Worker 或 Websocket 类不解析 TLS 握手,也不处理 SNI 和证书链。你硬在代码里写 ssl:// 或传 server.pem,结果只会是:
- 浏览器或小程序报
net::ERR_CONNECTION_REFUSED或Unexpected response code: 400 - Nginx 日志出现
upstream prematurely closed connection - OpenSSL 测试失败:
openssl s_client -connect your.domain:443 -servername your.domain连不上或提示 certificate verify failed
根本原因:Workerman 是 TCP 层框架,不是 Web 服务器。它只认 ws://127.0.0.1:2346 这种明文地址,WSS 必须由 Nginx 解密后转发。
Nginx 配置 WSS 代理的最小必要项
以下配置块必须完整出现在你的 server { ... } 中(监听 443 端口),缺一不可:
-
proxy_http_version 1.1:HTTP/1.0 不带Upgrade头,WebSocket 握手直接失败 -
proxy_set_header Upgrade $http_upgrade:把客户端发来的Upgrade: websocket原样透传 -
proxy_set_header Connection "upgrade":告诉 Nginx “这不是普通 HTTP,要升为 WebSocket” -
proxy_pass http://127.0.0.1:2346(末尾不加/):保留原始路径,让 Workerman 自己解析/ws或/realtime -
ssl_certificate和ssl_certificate_key必须指向完整证书链(fullchain.pem+privkey.pem),不能只放域名证书
示例 location 块(路径匹配前端 JS 里的 new WebSocket('wss://a.com/ws')):
location /ws {
proxy_pass http://127.0.0.1:2346;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 86400;
}
路径不匹配是 90% 的连接失败根源
Workerman 本身不校验 URL 路径,但 Nginx 的 location 是入口开关。常见错配:
- JS 连的是
wss://a.com/socket,Nginx 却只写了location /ws { ... }→ 请求被 fallback 到静态文件或 404 -
proxy_pass http://127.0.0.1:2346/(末尾有/)→ 把/socket剥掉,转发成http://127.0.0.1:2346,Workerman 收不到路径信息 - Workerman 启动时没指定 path(如
new Websocket('ws://127.0.0.1:2346')),但前端却连wss://a.com/api/ws→ Nginx 没配location /api/ws,压根不进代理块
建议统一用 location / + 前端显式写全路径,或固定一个前缀(如 /ws/),并在 JS 和 Nginx 中严格一致。
微信小程序连不上?先检查这三件事
微信强制校验标准 WSS 行为,和浏览器还不完全一样:
- 域名必须已在小程序后台「开发管理 → 服务器域名」中添加
wss://your.domain(结尾不能带/或路径) - 证书必须由可信 CA 签发(Let’s Encrypt 可以,自签、局域网 IP 证书、过期证书全都不行)
- 确保 Nginx 没开启
proxy_buffering on(默认是 off,但某些模板会开),否则小包延迟导致握手超时
验证命令(在服务器上跑):curl -I -k -H "Connection: Upgrade" -H "Upgrade: websocket" https://your.domain/ws,返回 101 Switching Protocols 才算通。
最易被忽略的点:Workerman 监听地址必须是 127.0.0.1,绝不能写 0.0.0.0 或公网 IP;Nginx 的 proxy_pass 必须指向这个本地地址。暴露明文 ws 端口到公网,等于绕过所有 TLS 保护。











