navigator.onLine仅反映浏览器联网状态,不保证实际通信;需结合online/offline事件、WebSocket心跳、指数退避重连及本地缓存同步实现可靠网络状态管理。

如何用 navigator.onLine 检测基础网络状态
navigator.onLine 是最轻量的在线状态判断方式,但它只反映浏览器是否“认为”联网——比如断开 WiFi 后立即返回 false,但连着 WiFi 却因 DNS 失败或服务器宕机而无法通信时,它仍返回 true。
所以它适合做第一层快速响应,不能替代真实连接检测:
- 监听
window.addEventListener('online', handler)和'offline'事件,但注意:这些事件可能延迟触发(尤其从休眠唤醒后) - 首次进入游戏时必须主动读一次
navigator.onLine,因为页面加载时事件不会触发 - 不要仅靠它决定是否发请求——它不保证 WebSocket 或
fetch能通
WebSocket 断线时怎样捕获真实错误并提示用户
HTML5 小游戏常用 WebSocket 实时通信,但 onclose 和 onerror 触发时机与原因差异很大:
-
onclose在连接被服务端关闭、主动调用close()或底层 TCP 断开时触发,event.code可区分原因(如1006表示异常关闭) -
onerror不会携带具体错误信息,且某些浏览器(如 Safari)在连接失败初期不触发它,只静默失败 - 必须配合心跳机制:每隔 5–10 秒发一次
ping帧(或自定义{"type":"ping"}),超时未收到pong就判定为断线
示例片段:
立即学习“前端免费学习笔记(深入)”;
ws.onclose = (e) => {
if (e.code === 1006 || !e.wasClean) {
showNetworkTip('连接已中断,请检查网络');
startReconnectTimer();
}
};
重连逻辑该不该自动重试?怎么控制频率和体验
自动重连是必要的,但无限制重试会加重服务端压力,也容易让用户困惑。关键不是“要不要重连”,而是“何时重连、重连几次、怎么告诉用户”:
- 首次断线后立即尝试重连(0 秒延迟),失败则按指数退避:1s → 2s → 4s → 8s,最多 5 次
- 每次重连前检查
navigator.onLine,若为false,暂停重连并显示“请检查网络连接”,不再计时等待 - 界面上需明确状态:断线时灰掉操作按钮,显示“正在重连…(3/5)”,而非静默等待
- 若重连全部失败,保留最后一条服务器消息(如“房间已解散”),并提供手动重试按钮,而不是直接退出游戏
本地缓存操作 + 网络恢复后同步的实现要点
对非实时强依赖的操作(如背包道具使用、聊天输入),可在断线时暂存到 localStorage 或内存队列,等重连成功后再补发:
- 每条待同步操作必须带唯一
id和时间戳,避免重复提交 - 服务端需支持幂等写入(例如用
INSERT ... ON CONFLICT DO NOTHING或业务层判重) - 同步失败时要回滚本地状态,并把失败项移到单独队列,人工干预前不再自动重试
- 切勿缓存移动类操作(如角色位移)——这类数据过期快,补发会导致位置跳跃或冲突
真正难的不是检测断线,而是判断“这条数据还值不值得发”。用户点了一次“使用药水”,网络闪断又恢复,你得知道该补发;但他在断线期间狂点 10 次,就得合并或丢弃冗余请求。这个边界,代码写不死,得靠场景想清楚。











