Workerman本身不内置自动广播或分组推送逻辑,仅提供基础WebSocket帧收发;需自行实现连接状态跟踪、screen_id标识、心跳保活及离线消息补发机制,否则易导致大屏掉线、数据不同步和性能瓶颈。
Workerman 本身不内置 WebSocket 服务端的“自动广播”或“按分组推送”逻辑,你得自己搭好连接管理 + 消息路由,否则大屏刷新会卡、掉线、数据不同步。
为什么直接 new Worker('websocket://0.0.0.0:2346') 不够用?
单纯启动一个
实例只负责收发原始帧,没有连接状态跟踪、没有客户端分组、没有心跳保活——大屏页面一旦刷新或网络抖动,
不触发、连接残留、新连接无法继承旧状态。更麻烦的是:你没法区分哪个消息该推给哪块屏。
实操建议:
必须用
的
或自定义
(配合
扩展)标识每个大屏终端
用全局数组或
存储“屏ID → connection 对象”的映射,避免用
全量遍历(连接数一过百就明显延迟)
在
里解析 URL 查询参数,例如
,提取
并绑定到
如何安全地向指定大屏推送 JSON 数据?
Workerman 的
只接受字符串,但大屏前端通常 expect
。直接
发送没问题,但要注意三件事:
必须检查
再 send,否则可能触发 warning:“trying to write on closed connection”
避免在
里直接
或阻塞 IO(比如同步查 MySQL),会导致整个进程卡住;改用
或
(需
workerman
/mysql)
如果推送频率高(如每秒 10+ 条),启用
前务必确认证书链完整,否则 Chrome 会静默断开 wss 连接且不报错
示例片段:
怎么让 50+ 大屏稳定长连不掉线?
默认配置下,Nginx、SLB、甚至某些企业防火墙会在 60 秒无数据时主动踢掉 TCP 连接。Workerman 不自动发 ping/pong,得手动加心跳。
在
设置定时器:
在
里拦截
/
,并重置连接活跃时间(Workerman 本身不维护 lastActiveTime,得自己记)
Linux 内核参数要调:
(不能依赖它,仅作兜底)
禁用
时的
默认值(2048),改用
并配好 ulimit -n
真正难的不是推一条数据,而是当某块屏断网重连后,如何补发它离线期间的 37 条关键指标更新——这需要你在推送前把变更写入
或本地
,并在重连时按
拉取未读事件。这个环节没人替你做。
WorkeronCloseWebsocketConnection$connection->id$_SESSIONSessionRedisforeach($worker->connections)onConnectwss://api.example.com?screen_id=dashboard-01screen_id$connection->screen_id$connection->send()JSONjson_encode($data)$connection->isConnected()onMessagesleep()AsyncTcpConnectionMySQLi::queryAsync$connection->enableSSL = true// 推送前校验
if ($connection->isConnected() && isset($connection->screen_id)) {
$connection->send(json_encode(['type' => 'stats', 'data' => $payload], JSON_UNESCAPED_UNICODE));
}onConnect$connection->pingTimer = Timer::add(25, function() use ($connection) { $connection->send('{"type":"ping"}'); });onMessagepingpongnet.ipv4.tcp_keepalive_time = 300Worker::$daemonize = truemax_connectionsWorker::$maxConnections = 10000Redis Streamleveldbscreen_id