workerman 5.2.3 中连接超时需分协议实现:tcp 依赖手动记录时间戳+定时清理;websocket 推荐使用内置 ping_interval/ping_not_response_limit 心跳机制,兼顾兼容性与简洁性。

Workerman 5.2.3 中设置连接超时时间,核心不是靠单一参数“一刀切”,而是分场景、分协议(TCP / WebSocket)配合连接保活逻辑 + 主动清理机制来实现。直接设个 timeout 属性并不存在,必须手动组合关键步骤。
TCP 连接超时控制(推荐方式)
适用于纯 TCP 长连接服务(如自定义协议、IM底层通道):
-
在
onConnect中启用长连接并记录初始时间$worker->onConnect = function ($connection) { $connection->keepConnection = true; // 必须开启,否则发完即断 $connection->lastMessageTime = time(); // 初始化活跃时间戳 }; -
在
onMessage中更新时间戳$worker->onMessage = function ($connection, $data) { $connection->lastMessageTime = time(); // 每次收消息就刷新 // ……业务处理 }; -
启动定时器,每 55 秒扫描并关闭超时连接(阈值设为 60 秒)
Worker::addTimer(55, function () { $now = time(); foreach (Worker::$connections as $connection) { if ($now - $connection->lastMessageTime > 60) { $connection->close(); } } });⚠️ 注意:定时器间隔(55s)必须严格小于超时阈值(60s),否则可能误杀刚发完消息的连接。
WebSocket 连接超时(含心跳保活)
WebSocket 协议本身支持 ping/pong,Workerman 5.2.3 提供了更简洁的内置心跳配置:
-
直接设置
ping_interval和ping_not_response_limit$ws_worker = new Worker('websocket://0.0.0.0:2000'); $ws_worker->ping_interval = 25; // 每 25 秒发一次 ping $ws_worker->ping_not_response_limit = 2; // 连续 2 次没收到 pong 就断开✅ 这种方式自动处理心跳帧收发与超时判定,兼容所有标准 WebSocket 客户端,无需手动解析
onMessage中的 ping 帧。 -
若需兼容非标准客户端或自定义心跳包(如发送
\x00),则要:- 手动定时发送(
Worker::addTimer) - 在
onMessage中识别该帧,并重置$connection->lastMessageTime - 同时保留上面的定时清理逻辑
- 手动定时发送(
补充:避免连接堆积的关键点
- 确保
onClose回调中清理关联资源(如用户在线状态、连接映射表) - 不要遗漏
keepConnection = true—— 这是所有超时逻辑生效的前提,否则连接在onMessage返回后立即关闭 - 超时阈值建议不低于 45 秒,避开常见 NAT 网关 60 秒静默断连窗口
不复杂但容易忽略











