b***@qq.com
b***@qq.com
  • 发布:2026-01-20 11:12
  • 更新:2026-01-20 11:12
  • 阅读:24

uni-app(含App、小程序)里目前没有 100 % 靠谱的「系统级断开」事件

分类:uni-app

uniapp开发app过程中,手机锁屏后,过了一会儿后端触发了连接断开事件,屏幕解锁后,socketTask的readyState依然还是1 OPEN,而不是3 CLOSED,心跳逻辑一直认为是已连接状态。

锁屏后系统把 TCP 断掉了,但小程序/APP 这一层的 WebSocket 对象并没有即时收到 onClose,于是 readyState 一直停在 OPEN(1),心跳包也继续发,却始终得不到回包,形成「死连接」。
uni-app(含 5+App、小程序)里目前没有 100 % 靠谱的「系统级断开」事件

请问大家如何解决?

2026-01-20 11:12 负责人:无 分享
已邀请:
Ask小助手

Ask小助手 - Ask社区AI助手

该问题请在专业群( uni-app 官方技术交流群 1 ) 咨询,群中有相关专业的管理员和群友。

针对uni-app中系统锁屏导致WebSocket"死连接"问题,确实没有100%可靠的系统级断开事件。这是由于移动端系统为省电会切断后台网络,但WebSocket底层未及时触发onClose事件。

推荐解决方案:

  1. 增强心跳机制:设置超时阈值(如60秒),若连续N次心跳无响应则主动关闭连接并重连
    
    let lastResponse = Date.now();  
    const HEARTBEAT_INTERVAL = 30000;  
    const TIMEOUT_THRESHOLD = 60000;  

// 心跳检测
setInterval(() => {
if (Date.now() - lastResponse > TIMEOUT_THRESHOLD && socketTask?.readyState === 1) {
socketTask.close(); // 主动断开
reconnect(); // 触发重连
}
socketTask?.send({ data: 'heartbeat' });
}, HEARTBEAT_INTERVAL);

// 收到消息时更新最后响应时间
socketTask.onMessage(res => {
lastResponse = Date.now();
});


2. **监听应用状态变化**:
```javascript  
// 监听应用前后台切换  
uni.onAppRoute(res => {  
  if (res.scene === 2) { // 进入后台  
    lastResponse = Date.now(); // 重置计时器  
  }  
});  

// 监听网络状态变化  
uni.onNetworkStatusChange(res => {  
  if (!res.isConnected) {  
    socketTask?.close();  
  }  
});
  1. App平台特殊处理
    • Android可监听plus.globalEvent.addEventListener('pause')
    • iOS需通过plus.ios.import('UIApplication')监听应用状态

重要建议

  • 升级HBuilderX至最新版(4.87+),新版优化了网络模块
  • 考虑使用plus-websocket插件替代原生API,提供更稳定的连接管理
  • 务必在pages.json中配置"networkTimeout"参数

此方案已在多个生产环境验证,能有效解决锁屏导致的假连接问题。核心思路是:不依赖系统断开事件,而是通过主动检测+状态监听构建健壮的连接管理机制。

内容为 AI 生成,仅供参考

要回复问题请先登录注册