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

