swoole websocket服务必须监听0.0.0.0而非127.0.0.1才能接受外部连接;nginx反向代理需严格配置proxy_http_version 1.1、upgrade和connection头;须确保php以独立常驻进程运行且无任何输出污染http响应头。

确认 Swoole 服务监听地址不是 127.0.0.1
本地开发时容易把 Swoole\WebSocket\Server 绑定到 127.0.0.1,导致外部无法建立 TCP 连接,浏览器直接报 net::ERR_CONNECTION_REFUSED。Swoole 必须监听 0.0.0.0 才能接受来自 Nginx 或公网的握手请求。
- 检查启动代码中
new Swoole\WebSocket\Server('127.0.0.1', 9501)→ 应改为new Swoole\WebSocket\Server('0.0.0.0', 9501) - 用
ss -tuln | grep :9501(Linux)或netstat -an | findstr :9501(Windows)确认监听 IP 是*:9501或0.0.0.0:9501,而非127.0.0.1:9501 - 若用 Docker,还需检查
-p 9501:9501是否映射,且容器内未被防火墙拦截
Nginx 反向代理漏了 Upgrade 头转发
绝大多数线上 Swoole WebSocket 握手失败,根源在 Nginx 配置缺失关键三行——它把 Upgrade: websocket 请求当普通 HTTP 处理,后端根本收不到升级信号,自然不返回 101 Switching Protocols。
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- location 块中必须同时存在:
proxy_http_version 1.1;、proxy_set_header Upgrade $http_upgrade;、proxy_set_header Connection "upgrade"; -
$http_upgrade是 Nginx 内置变量,不能写成$upgrade或硬编码"websocket";引号必须是英文双引号 - 改完务必执行
nginx -t && nginx -s reload,否则配置不生效 - 若前端走的是 Cloudflare 或其他 CDN,需确认它们是否也透传了这两个头(部分免费版会 strip)
PHP-FPM 模式下误跑 WebSocket 服务
用 php start.php start 启动 Swoole 服务时,如果脚本被 Web 服务器(如 Apache/Nginx + PHP-FPM)直接执行,会导致进程秒退——PHP-FPM 是短生命周期模型,无法维持长连接,浏览器可能看到 101 响应但立刻断开(状态码 1006)。
- 确认 Swoole 服务是独立常驻进程:运行
ps aux | grep swoole,应看到类似php start.php start -d的后台进程 - 禁止将 Swoole 启动脚本放在 Web 目录下并通过浏览器访问(例如
http://site/start.php),这会触发 PHP-FPM 执行,必然失败 - Web 服务器只负责反向代理到 Swoole 监听的端口(如
http://127.0.0.1:9501),绝不应参与 Swoole 进程管理
Sec-WebSocket-Key 校验失败或响应头污染
Swoole 默认会校验 Sec-WebSocket-Key 并生成合法的 Sec-WebSocket-Accept,但如果中间有输出(比如调试 echo、BOM、Notice 错误、日志函数),响应体就会提前发送,导致 HTTP 头不完整,浏览器静默关闭连接。
- 确保启动脚本顶部无 BOM、无空格、无
print/echo/var_dump;关闭display_errors,避免 Notice/Warn 输出到响应体 - 在
onHandshake回调中加日志时,用Swoole\Coroutine::sleep(0.001)或写入文件,别直接 echo - 用
curl -i -N -H "Upgrade: websocket" -H "Connection: Upgrade" http://your-domain.com/ws手动测试,观察是否返回干净的HTTP/1.1 101 Switching Protocols及正确头字段 - 特别注意:某些 Composer 包(如旧版 monolog)在初始化时会触发 warning,建议在 Swoole 启动前调用
error_reporting(0)










