应监听 visibilitychange 事件精准识别息屏/亮屏状态,hidden 时标记不立即断连,visible 时按后台时长决定是否重连;重连前主动 close 并延时新建,结合心跳与 onclose 双重判断断连,缓存业务消息并控制重试频率。

移动端息屏会导致 WebSocket 连接实际中断,但 JavaScript 无法及时感知——因为息屏后定时器暂停、心跳停止、TCP 连接在 NAT 或代理层超时被静默断开。真正的解决思路不是“防止断开”,而是“精准识别息屏场景 + 合理触发重连”。
监听 visibilitychange 判断页面可见性状态
这是最可靠、兼容性最好的前端信号。`document.visibilityState` 能准确反映页面是否处于前台(visible)或后台/息屏(hidden):
- 在 `mounted` 或初始化阶段绑定事件:
document.addEventListener('visibilitychange', this.handleVisibilityChange) - 息屏时(
visibilityState === 'hidden')记录时间戳,不立即关连接,只做标记 - 亮屏时(
visibilityState === 'visible')计算停留后台时长,超过阈值(如 10 秒)再执行重连 - 避免锁屏瞬间就重连——此时旧连接可能尚未彻底释放,易触发
InvalidStateError
重连前主动关闭旧连接并延时新建
息屏后服务端大概率已断开连接,客户端残留的 WebSocket 实例处于假死状态(readyState === 0 or 1 但不可用)。必须清理后再建新链路:
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
- 调用
this.ws?.close(4999, "visibility_restore")主动关闭,确保资源释放 - 关闭后等待 1–1.5 秒再
new WebSocket(...),避开浏览器内部状态切换延迟 - 重连前检查
wsRef是否存在,有则先close()并置为null,防止多实例并发 - 设置
isReconnecting = true标志,避免onclose多次触发重连逻辑
结合心跳与 onclose 做双重断连确认
仅靠 visibilitychange 不够——比如用户切到其他 App 但屏幕未熄,或息屏时间短于服务端心跳超时。需叠加网络层感知:
- 连接建立后启动心跳:每 25–30 秒发
{type: "ping"},服务端须回{type: "pong"} - 客户端维护 pong 超时计时器(建议 5–8 秒),未收到即主动
ws.close(4999) - 在
onclose中判断:event.code === 1006 || event.code >= 4000视为异常,触发重连;code === 1000或wasClean === true则不重连 - 息屏唤醒后的重连,应携带重连标识(如
{type: "reconnect", ts: Date.now()}),便于服务端恢复会话上下文
优化用户体验与资源控制
重连不是技术闭环,而是用户可感知的体验环节:
- 息屏期间暂停发送业务消息,但可缓存本地待发队列(如弹幕输入、表单草稿),设 TTL 防堆积
- 重连成功后,先发握手帧再恢复订阅,避免旧连接残留消息干扰新会话
- 若连续重连失败 3 次,暂停自动重试,改为用户点击“重试”手动触发,减少无效请求
- 页面隐藏时暂停心跳定时器和重连定时器,避免后台耗电;亮屏后再恢复
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










