workerman 4 中 websocket 心跳检测与空闲断开核心依赖 onmessage 捕获心跳包、connection->lastrequesttime 记录活跃时间及定时器轮询清理;需手动注册定时器检查 time() - lastrequesttime > 超时阈值(如60秒)并调用 close(),默认不开启空闲检测。

Workerman 4 中 WebSocket 心跳检测和空闲连接超时断开,核心靠 onMessage 捕获客户端心跳包 + connection->lastRequestTime 记录活跃时间 + 定时器轮询清理。不依赖客户端定时发 ping,服务端主动管理更可靠。
配置连接空闲超时时间
在 Worker 实例创建后、启动前,设置 connectionClass 并指定超时阈值(单位:秒):
$worker = new Worker('websocket://0.0.0.0:2346');
$worker->count = 4;
// 设置每个连接最大空闲时间(例如 60 秒)
$worker->connectionsTimeout = 60;
<p>// 可选:自定义 Connection 类,便于扩展逻辑
$worker->connectionClass = \Workerman\Connection\TcpConnection::class;
</p>注意:Workerman 4 默认不开启空闲检测,需手动添加定时器实现。
注册定时器定期清理空闲连接
在 Worker::onWorkerStart 中启动一个全局定时器,遍历所有 WebSocket 连接,检查最后通信时间:
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- 用
$connection->lastRequestTime获取上次收/发消息时间戳 - 若当前时间 -
lastRequestTime > 超时阈值,调用$connection->close() - 建议间隔设为超时值的 1/3~1/2(如超时 60 秒,定时器每 20 秒执行一次)
Worker::onWorkerStart = function ($worker) {
// 每 20 秒检查一次空闲连接
Timer::add(20, function () use ($worker) {
$timeNow = time();
foreach ($worker->connections as $connection) {
if ($connection->isWebSocketConnection
&& $timeNow - $connection->lastRequestTime > 60) {
$connection->close();
}
}
});
};
客户端心跳包识别与刷新 lastRequestTime
WebSocket 协议中,客户端发送的 Ping 帧 不会触发 onMessage,但 Workerman 4 会自动响应并更新 lastRequestTime;真正需要处理的是客户端自定义的心跳消息(如 JSON:{"type":"ping"}):
- 在
onMessage中判断消息内容是否为心跳,是则不业务处理,仅确保lastRequestTime被刷新(默认已自动更新) - 可额外返回
{"type":"pong"}做双向确认(非必须) - 避免在心跳处理中执行耗时操作,防止阻塞连接检测
$worker->onMessage = function ($connection, $data) {
$msg = json_decode($data, true);
if (isset($msg['type']) && $msg['type'] === 'ping') {
$connection->send(json_encode(['type' => 'pong']));
return; // 不做其他处理,保持连接活跃
}
// 其他业务逻辑...
};
补充:强制关闭前可通知客户端
想提升体验,可在 close 前发送提示消息:
- 调用
$connection->send()发送下线提醒(需在 close 前且连接未断) - 注意 catch 异常,防止 send 失败导致定时器中断
- 例如:
$connection->send('{"event":"disconnect","reason":"idle_timeout"}');
服务端心跳管理本质是“时间戳 + 定时扫描”,不复杂但容易忽略定时器注册时机和连接类型判断。做好这几点,空闲连接就能干净退出,资源不堆积。









