uni-app APP后台运行时,部分安卓手机websocket无法正确触发onSocketClose

uni-app APP后台运行时,部分安卓手机websocket无法正确触发onSocketClose

开发环境 版本号 项目创建方式
Windows win10 HBuilderX

产品分类:uniapp/App

PC开发环境操作系统:Windows

HBuilderX类型:正式

HBuilderX版本号:3.2.16

手机系统:Android

手机系统版本号:Android 10

手机厂商:华为

手机机型:未知

页面类型:vue

vue版本:vue2

打包方式:离线

示例代码:

uni.connectSocket({
url: '',
success: res => {
console.log(res);
}
});
uni.onSocketOpen(res => {
if (this.autoOff) {
this.working = true;
if(this.autoOff) getApp().globalData.navi.playTTS("虫连成功", true);
}
this.sendLoaction();
this.localTimer = setInterval(e => {
this.sendLoaction();
}, 10000);
this.workTimer = setInterval(e => {
this.updateTimer();
}, 1000);
});
uni.onSocketMessage(res => {
let obj = this.dealData(res.data);
console.log(obj, this.orderinfo);
if (obj.id && !this.myorder.id && this.ignoreArr.indexOf(obj.id) < 0) {
// TODO
}
if (obj.voice && (this.myorder.id || obj.force == 1)) {  
}  
});
//监听打开失败
uni.onSocketError(function(res) {
console.log('WebSocket连接打开失败,请检查!', res);
});
uni.onSocketClose(e => {
console.log('close Ws', e);
this.working = false;
clearInterval(this.workTimer);
clearInterval(this.localTimer);
this.getWork();
});

操作步骤:

一、建立连接后,用户将切换APP切换至后台

二、观看几分钟的视频后,自动断线。

预期结果:

正确触发onSocketClose的回调。

实际结果:

不触发onSocketClose的回调。导致重复调用时间计时

bug描述:

不触发onSocketClose


更多关于uni-app APP后台运行时,部分安卓手机websocket无法正确触发onSocketClose的实战教程也可以访问 https://www.itying.com/category-93-b0.html

6 回复

这种情况还能回到应用中吗 回到应用表现是什么样的

更多关于uni-app APP后台运行时,部分安卓手机websocket无法正确触发onSocketClose的实战教程也可以访问 https://www.itying.com/category-93-b0.html


可以正常返回应用,没有重新打开APP的过程。

一开始我以为是定时器太多的问题,现在把定时器简化成一个。今天上午测试还是没有正确触发

回复 5***@qq.com: 请提供一下完整HXdemo示例我们这边测试下 还有如何得知已断开?

回复 DCloud_Android_ST: 我们先找了个第三方的插件试试,如果还不行,再反馈。谢谢了

在uni-app中,当APP进入后台运行时,部分安卓系统(特别是华为等定制系统)会限制WebSocket连接以节省电量。这可能导致onSocketClose回调无法正常触发。

问题分析:

  1. 系统休眠策略:安卓10及以上版本加强了后台限制,当APP进入后台后,系统可能强制关闭网络连接
  2. 心跳机制缺失:你的代码缺少WebSocket心跳机制,无法维持长连接
  3. 后台运行权限:需要配置后台运行权限和网络保持

解决方案:

  1. 添加心跳机制
// 在onSocketOpen中添加心跳
uni.onSocketOpen(res => {
  // ...原有代码...
  
  // 添加心跳(每30秒发送一次)
  this.heartbeatTimer = setInterval(() => {
    if (this.working) {
      uni.sendSocketMessage({
        data: JSON.stringify({type: 'heartbeat'})
      });
    }
  }, 30000);
});

// 在onSocketClose中清除
uni.onSocketClose(e => {
  // ...原有代码...
  clearInterval(this.heartbeatTimer);
});
  1. 配置后台运行: 在manifest.json中添加:
{
  "app-plus": {
    "background": {
      "mode": "socket",
      "keepalive": true
    }
  }
}
  1. 监听应用状态变化
// 监听APP进入后台/前台
uni.onAppHide(() => {
  // APP进入后台时主动发送心跳
  if (this.working) {
    uni.sendSocketMessage({
      data: JSON.stringify({type: 'background_heartbeat'})
    });
  }
});

uni.onAppShow(() => {
  // APP回到前台时检查连接状态
  this.checkConnection();
});
  1. 使用uni-push替代: 对于需要后台持久连接的需求,建议使用uni-push服务,它专门处理了各种系统的后台限制问题。

  2. 华为手机特殊处理: 华为手机需要在设置中允许APP的后台活动权限,可以在代码中检测并提示用户:

// 检测到华为设备时提示用户
if (plus.os.vendor === 'huawei') {
  // 提示用户去设置中允许后台运行
}
回到顶部