uni-app uni.connectSocket连接成功后,使用uni.chooseImage、uni.chooseVideo打开相机会自动断开Socket连接

uni-app uni.connectSocket连接成功后,使用uni.chooseImage、uni.chooseVideo打开相机会自动断开Socket连接

产品分类:

uniapp/App

PC开发环境操作系统:

Windows

PC开发环境操作系统版本号:

Windows 11

HBuilderX类型:

正式

HBuilderX版本号:

4.87

手机系统:

Android

手机系统版本号:

Android 15

手机厂商:

一加

手机机型:

一加ace2pro

页面类型:

vue

vue版本:

vue3

打包方式:

云端

项目创建方式:

HBuilderX

示例代码:

<template>
<view>
<input type="text" v-model="mes" placeholder="消息" />
<button @click="sendSocketMessageStr_2">发送</button>
<button @click="CloseSokt">关闭</button>
<button @click="InitApi">重新连接</button>
<button @click="openchooseImage">打开相机</button>
</view>
</template> 
<script>
export default {
data() {
return {
mes: "",
heartbeatTimer: null,
socketTask: {},
kf: 'xxx',
UserHubId: '', //
isshow:false,//判断是否连接成功
access_token: 'xxx',
}
},
mounted() {
this.InitApi()
},
methods: {
InitApi() {
this.socketTask = uni.connectSocket({
url: 'wss://xxx/xxx?kf=' + this.kf + '&amp;access_token=' + this
.access_token,
success: () => {
console.log("正准备建立websocket中...");
// 返回实例
return this.socketTask
},
faile(err) {
console.log("执行了")
}
});
this.setupSocketListeners()
},
setupSocketListeners() {
//监听链接事件
this.socketTask.onOpen((res) => {
this.sendSocketMessageStr_1(`{"protocol":"json", "version":1}${String.fromCharCode(0x1e)}`)
console.log("WebSocket连接正常!");
})
//监听连接关闭事件
this.socketTask.onClose((res) => {
console.log("WebSocket连接关闭!", res);
})
//监听错误事件
this.socketTask.onError((res) => {
console.log("WebSocket错误!", res);     
// console.log("WebSocket错误!", JSON.parse(res)); //报错
// console.log("WebSocket错误!",JSON.stringify(res)); //返回{}
// console.log("WebSocket错误!",res[0]); //返回undefined
})
//监听服务器的消息事件
this.socketTask.onMessage((res) => {
console.log("WebSocket服务器的消息事件", res);
// 1. 先去除尾部的分隔符 \u001e
let dataStr = res.data;
if (dataStr.charCodeAt(dataStr.length - 1) === 0x1e) {
dataStr = dataStr.substring(0, dataStr.length - 1);
}
// 2. 解析 JSON 字符串
const dataObj = JSON.parse(dataStr);
console.log("解析后的数据对象:", dataObj);
console.log("type:", dataObj.type);
console.log("target:", dataObj.target);
console.log("arguments:", dataObj.arguments);
if (dataObj.target === 'UserInfo') {
this.UserHubId = dataObj.arguments[0]
console.log("this.UserHubId", this.UserHubId)
}
})
},
CloseSokt() { //关闭
this.socketTask.close({
success: () => {
console.log("已关闭")
},
fail: (err) => {
console.log("关闭出错", err)
}
})
},
sendSocketMessageStr_1(msg) {
this.socketTask.send({
data: msg,
success: (data) => {
console.log("成功发送信息", data)
},
fail: (err) => {
console.log("错误信息", res)
}
})
},
//发送消息
sendSocketMessageStr_2() {
const msgId = Date.now().toString() + Math.random().toString(36).substr(2, 9);
const msgObj = {
type: 1,
target: "SendMessage",
arguments: [{
UserHubId: this.UserHubId,
MsgId: msgId,
ChatTxt: this.mes,
TxtType: 0,
duration: 0
}]
};
// 将对象转换为JSON字符串,并添加分隔符(根据服务器要求,可能是0x1e)
const msgStr = JSON.stringify(msgObj) + String.fromCharCode(0x1e);
console.log('msgObj', msgObj)
this.socketTask.send({
data: msgStr,
success: (data) => {
console.log("成功发送信息", data)
},
fail: (err) => {
console.log("错误信息", res)
}
})
},
//打开相机
openchooseImage() {
uni.chooseImage({
count: 6, //默认9
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
sourceType: ['camera'], //从相册选择
success: function (res) {
console.log(JSON.stringify(res.tempFilePaths));
}
});
}
}
}
</script>

操作步骤:

Socket握手成功后,选择“打开相机”停留5~10秒在返回发送信息,会直接报WebSocket错误!, [Object] {}

预期结果:

Socket握手成功后,用户打开相机后无论停留多少秒Socket连接不会自动断开,应该和从相册中选择一致,相册选择不会自动断开。

实际结果:

Socket握手成功后,选择“打开相机”停留5~10秒在返回发送信息,会直接报WebSocket错误!, [Object] {}

bug描述:

用户正常聊天和从相册中选择图片和视频都是正常的,但是如果用户在拍照或者录制视频时停留在相机时间过长,Socket会自动断开连接,并且onError没有错误提示(只会返回[Object])使用JSON.parse(),JSON.stringify(),err[0],都不行都返回,也没有走onClose连接关闭事件,以下是demo也有这个问题。


更多关于uni-app uni.connectSocket连接成功后,使用uni.chooseImage、uni.chooseVideo打开相机会自动断开Socket连接的实战教程也可以访问 https://www.itying.com/category-93-b0.html

2 回复

该bug反馈内容完整,包含标题、详细描述、可运行代码示例、清晰复现步骤、预期与实际结果及分类信息,便于复现验证。反馈中明确说明了环境(HBuilderX 4.87/Android 15)、问题现象(调用相机导致Socket断开)及异常表现(onError仅返回[Object]且未触发onClose)。
经分析,此问题并非uni-app框架bug,而是Android系统特性导致:当调用uni.chooseImage/uni.chooseVideo时,应用会短暂进入后台状态,Android 15的电源管理机制会主动断开后台应用的网络连接(包括WebSocket)。知识库文档https://uniapp.dcloud.net.cn/api/request/websocket.html明确说明"在各平台运行时,网络API受系统限制",且未承诺后台保活能力。
用户预期"连接不会自动断开"不符合移动端系统规范——iOS/Android均会对后台应用进行资源限制。实际结果属正常系统行为,非框架缺陷。建议采用标准解决方案:1. 实现断线重连机制;2. 在onShow生命周期中检测并恢复连接;3. 添加心跳包维持活跃状态。无需修复框架,应调整业务逻辑适配移动平台特性。 内容为 AI 生成,仅供参考

更多关于uni-app uni.connectSocket连接成功后,使用uni.chooseImage、uni.chooseVideo打开相机会自动断开Socket连接的实战教程也可以访问 https://www.itying.com/category-93-b0.html


这是一个典型的Android平台WebSocket后台保活问题。当uni.chooseImage或uni.chooseVideo调用相机时,应用会进入后台状态,Android系统可能会为了省电而终止WebSocket连接。

解决方案:

  1. 使用uni.onAppShow/onAppHide监听应用状态
onLoad() {
  // 应用从后台切回前台时
  uni.onAppShow(() => {
    if (this.socketTask && this.socketTask.readyState !== 1) {
      this.reconnectSocket();
    }
  });
  
  // 应用进入后台时
  uni.onAppHide(() => {
    this.lastActiveTime = Date.now();
  });
}
  1. 实现自动重连机制
reconnectSocket() {
  if (this.reconnecting) return;
  
  this.reconnecting = true;
  this.socketTask.close();
  
  setTimeout(() => {
    this.InitApi();
    this.reconnecting = false;
  }, 1000);
}
  1. 优化WebSocket配置
this.socketTask = uni.connectSocket({
  url: 'wss://xxx/xxx',
  header: {
    'content-type': 'application/json'
  },
  protocols: [''],
  success: () => {
    console.log("正准备建立websocket中...");
  },
  fail: (err) => {
    console.log("连接失败", err);
  }
});
  1. 添加心跳保活(如果服务器支持)
startHeartbeat() {
  this.heartbeatTimer = setInterval(() => {
    if (this.socketTask && this.socketTask.readyState === 1) {
      this.socketTask.send({
        data: 'ping',
        success: () => {
          console.log('心跳发送成功');
        }
      });
    }
  }, 30000); // 30秒一次
}
回到顶部