必须在连接建立、断开、心跳维持三节点同步更新计数器;初始化全局计数器用static属性;onconnect初即+1并广播;onclose前校验uid再-1;http接口实时查询;启用心跳机制防强退残留。

要让Workerman主动推送信息时能准确统计当前在线人数,必须在连接建立、断开、心跳维持三个关键节点同步更新计数器,不能只依赖客户端上报或定时轮询。
初始化全局在线人数计数器
在Worker启动前,用PHP的$_SERVER或静态变量初始化一个可被所有进程共享的计数器。推荐使用pcntl_fork环境下的static属性,避免Redis等外部依赖引入延迟和单点故障。
在start_websocket.php最顶部添加:
Worker::$onWorkerStart = function($worker) {<br> self::$online_count = 0;<br>};
注意:不要用global $count,它在多进程下不共享;也不要直接用$_SESSION,WebSocket连接无Session上下文。
连接建立时+1
在$ws_worker->onConnect回调中执行计数加一,并广播最新人数:
第一步:获取当前连接句柄
第二步:执行self::$online_count++
第三步:调用$ws_worker->connections遍历所有连接并发送{"type":"online","count":self::$online_count}
这一步必须放在onConnect最开始,否则可能出现连接已建立但计数未更新的窗口期,导致新用户看到的在线数比实际少1。
连接关闭时-1
方法一:在$ws_worker->onClose中直接减一
self::$online_count = max(0, self::$online_count - 1);
一款AI图像与设计工具,主要用于将文本渲染为图片并返回临时本地文件路径,支持可选的 data URI。适用于 Clawhub 或 Codex,用于将纯文本或带样式的文本进行转换,适合需要提升相关任务效率的用户。
方法二:配合心跳检测做双重校验(更可靠)
给每个连接绑定唯一UID后,在onClose里先查该UID是否真实存在,再减一。防止恶意伪造close包导致计数错乱。
【务必检查$connection->uid是否存在】,否则攻击者可循环触发onClose使计数归零。
用HTTP接口实时获取当前人数
起一个独立的HTTP Worker监听端口(如8081),仅响应GET请求:
$http_worker = new Worker('http://0.0.0.0:8081');<br>$http_worker->onMessage = function($connection, $request) {<br> $connection->send(json_encode(['online' => self::$online_count]));<br>};
前端可通过fetch('/status')或curl http://your-domain:8081拿到实时数字,无需WebSocket连接也能查。
解决强退导致的计数残留
客户端异常断网时,Workerman不会立即触发onClose,默认等待60秒超时才清理连接。这会导致计数虚高。
启用心跳机制:在onConnect中设置$connection->pingInterval = 25;,并在onMessage里拦截ping帧;同时设置$connection->closeAfterPingTimeout = 45;。
这样只要客户端45秒内没回pong,连接自动关闭→触发onClose→执行-1操作。










