workerman 5.2.3 实现 websocket 长连接需三者协同:正确使用 websocket:// 协议初始化、显式设置 maxlifetime 控制连接寿命、客户端与服务端双向心跳保活,并规避 nginx 超时等部署陷阱。

Workerman 5.2.3 实现 WebSocket 长连接,核心不是“开启一个开关”,而是通过协议适配、连接生命周期管理与心跳机制三者协同来维持稳定通信。它默认就支持长连接,关键在于你是否正确配置了 WebSocket 协议监听、是否处理了超时与异常断开,以及客户端是否配合保活。
确认使用 WebSocket 协议监听
必须用 websocket:// 协议初始化 Worker,不能写成 tcp:// 或 http://。这是 Workerman 自动启用 WebSocket 握手和帧解析的前提:
- 正确写法:
$ws = new Worker('websocket://0.0.0.0:8000'); - 错误写法:
new Worker('tcp://0.0.0.0:8000')—— 这只会建立裸 TCP 连接,不走 WebSocket 协议栈,浏览器new WebSocket()会直接失败 - Workerman 5.2.3 内置 WebSocket 解析器,无需额外安装扩展或手动处理 Sec-WebSocket-Key 等握手细节
设置连接最大存活时间(maxLifetime)
长连接≠永不断开。Workerman 默认不限制单连接时长,但实际中需防空闲连接堆积。推荐在 onConnect 中为每个连接显式设 maxLifetime:
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
-
$connection->maxLifetime = 3600;表示该连接最多存活 1 小时(单位:秒) - 该值从连接建立时刻开始倒计时,无论是否有收发数据,超时后 Workerman 主动 close
- 若需真正“按需持久”,可设为 0(表示不限时),但务必搭配心跳机制,否则 NAT/防火墙可能静默断连
实现双向心跳保活(客户端 + 服务端)
仅靠 maxLifetime 不足以应对中间网络设备(如路由器、代理)的空闲断连。必须主动发送心跳包:
-
服务端定时心跳:用
Worker::setTimer()或Connection::send()定期向客户端发 ping 消息(如{"type":"ping"}) -
客户端响应:前端监听
onmessage,识别 ping 后立即回传 pong,避免被服务端误判为失联 -
服务端超时检测:可在连接对象上记录最后收到消息时间戳,结合定时器检查;若超过阈值(如 90 秒)未收任何数据,主动
$connection->close()
避免常见断连陷阱
很多“长连接断开”其实和 Workerman 本身无关,而是部署或环境导致:
- Nginx 反向代理默认 60 秒超时:需在 location 块中加
proxy_read_timeout 3600;和proxy_send_timeout 3600; - PHP-FPM 不参与 WebSocket 通信,确保你没把 WebSocket 路由错配到 FPM 的 fastcgi_pass 上
- Workerman 启动必须用 CLI 模式(
php start.php start),不能通过 Web 服务器直接执行 - Linux 系统级连接限制(如
net.ipv4.tcp_fin_timeout)一般不影响,但高并发下建议调优ulimit -n和net.core.somaxconn










