sharedworkerglobalscope是多标签页统一状态机的唯一可信源,所有状态变量须定义于其顶层作用域,由worker全权管理连接、心跳与重连,页面仅通过postmessage发送意图并接收带序列号的原子广播状态。
shared worker 的 globalscope(即 sharedworkerglobalscope)是实现多标签页统一状态机的天然载体——它不随页面生命周期起伏,所有同源页面共享同一份运行上下文,且具备跨端口通信能力。关键不在“能不能”,而在“怎么让状态真正一致、安全、可推演”。
状态必须收束到 SharedWorker 内部,禁止页面自行维护
每个标签页若各自维护连接状态、心跳计时、重连倒计时,必然导致状态分裂:A 页面显示“已连接”,B 页面却在重连中;C 页面刚打开就发了 subscribe 指令,而连接实际尚未建立。SharedWorkerGlobalScope 是唯一能承载全局单一事实(single source of truth)的位置。
实操上需做到:
- 所有状态变量(如
ws实例、readyState、lastPongTime、reconnectDelay、clientIdMap)只定义在 Worker 脚本顶层作用域,不暴露给页面 - 页面不得调用
new WebSocket()或setInterval管理心跳——这些行为必须由 Worker 全权接管 - 页面仅通过
port.postMessage()发送意图(如{ type: "subscribe", topic: "chat" }),Worker 解析后统一调度,不透传原始 WebSocket 方法
onconnect 是状态机初始化入口,不是被动中继
self.onconnect 是 SharedWorkerGlobalScope 唯一可靠的连接钩子,它在每个新页面接入时触发,且保证早于任何页面发送的消息。这里不是简单转发消息的地方,而是注册、校验、同步的起点。
典型处理逻辑包括:
- 从事件参数
event.ports[0]获取通信端口,并立即调用port.start() - 为该端口生成唯一
clientId(推荐crypto.randomUUID()),存入 Map 结构,绑定其生命周期 - 主动向新端口广播当前全局状态:
{ type: "status", state: currentStatus, sequence: ++seq },避免页面冷启动时状态缺失 - 监听该端口的
close事件(通过port.onclose或定期检查port.postMessage报错),及时清理映射表,防止内存泄漏
状态变更必须原子广播,且带序列号防乱序
多个页面可能在毫秒级内收到不同状态更新(如“connecting”→“open”→“reconnecting”),若无顺序保障,UI 可能闪退或卡在中间态。SharedWorkerGlobalScope 不提供消息排序,需手动设计。
建议做法:
- 每次状态变更(如连接成功、断开、重连中)都生成单调递增的
sequence,随消息一起广播 - 页面端缓存最近收到的
sequence,丢弃所有sequence ≤ 已处理值的旧状态消息 - 广播使用
self.clients.matchAll().then(clients => clients.forEach(c => c.postMessage(...))),但须过滤掉已关闭 client(检查c.frameType !== 'none'或捕获 postMessage 异常) - 禁止用
BroadcastChannel替代此广播——它会唤醒休眠标签页,违背“降低唤醒开销”的初衷
错误边界要兜底,避免单点崩溃导致全局失联
SharedWorkerGlobalScope 是单线程环境,一个未捕获异常(如 ws.send() 在 closed 状态下调用)会导致整个 Worker 退出,所有标签页瞬间失去连接管理能力。
防御性写法必不可少:
- 所有 WebSocket 回调(
onopen、onmessage、onerror、onclose)外层包裹try...catch,错误统一记录并触发降级(如广播{ type: "fatal", reason: e.message }) - 心跳定时器、重连定时器必须用
clearInterval/clearTimeout显式清理,尤其在重连前和连接关闭后 - 对
self.clients.matchAll()返回结果做空判断和 Promise catch,防止 client 列表查询失败中断后续流程 - 关键操作(如发送 ping、解析 pong、更新
lastPongTime)加 guard 条件:if (!ws || ws.readyState !== WebSocket.OPEN) return;











