lastMessageTime 是连接最后一次收到客户端数据的时间戳(秒级),由 onMessage 触发更新;连接建立时间需在 onConnect 中手动设 $connection->connectedAt = time()。

Workerman 中 lastMessageTime 是什么时间?
lastMessageTime 不是连接建立时间,而是该连接**最后一次收到客户端数据的时间戳**(单位:秒)。它由 Workerman 内部自动更新,每次调用 onMessage 回调时重置。如果你要记录「连接开始时间」,不能依赖它。
如何准确记录连接建立时间?
必须在 onConnect 回调中手动存入连接对象的自定义属性。Workerman 的 $connection 是一个对象,支持动态添加属性:
<pre class="brush:php;toolbar:false;">// 在 Worker 初始化后、start 前设置 onConnect
$worker->onConnect = function ($connection) {
$connection->connectedAt = time();
};之后可在任意地方读取:$connection->connectedAt。注意不要用 <code>$connection['connectedAt'](它不是数组)。
为什么不能在 onMessage 里用 lastMessageTime 算在线时长?
因为:
-
lastMessageTime初始值是连接建立时刻,但之后只要收过一次消息就会被覆盖——如果客户端连上后一直不发消息,这个值就停留在连接时间;一旦发了,就变成第一次发消息的时间,无法回溯。 - 心跳包或框架自动发送的 ping 也会触发
onMessage,导致lastMessageTime被刷新,干扰真实业务消息时间判断。 - 若需计算「已连接多少秒」,应始终用
time() - $connection->connectedAt,而不是time() - $connection->lastMessageTime。
连接时间相关操作的常见坑
几个容易出错的地方:
- 在
onClose中读$connection->connectedAt时,要先判断该属性是否存在——某些异常断开(如 TCP RST)可能没走完onConnect,此时属性未定义。 - 不要把时间存成字符串或毫秒值(如
Date.now()),time()返回的整数秒最稳妥,方便后续计算和比较。 - 如果用了 GatewayWorker 模式,
$connection是GatewayClient连接,lastMessageTime表示的是与 Gateway 进程通信的最后时间,和客户端真实连接时间无关,必须通过onConnect透传或业务协议携带时间戳。
连接时间看似简单,但混用 lastMessageTime 和连接起始时间是线上排查超时、踢人逻辑错误的高频原因。

















