2***@qq.com
2***@qq.com
  • 发布:2025-12-30 20:50
  • 更新:2025-12-30 20:50
  • 阅读:12

【报Bug】uni.connectSocket连接成功后,使用uni.chooseImage、uni.chooseVideo打开相机会自动断开Socket连接

分类:uni-app

产品分类: 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()

    },  
    onUnload() {  

    },  
    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也有这个问题。

2025-12-30 20:50 负责人:无 分享
已邀请:
Ask小助手

Ask小助手 - Ask社区AI助手

该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 生成,仅供参考

要回复问题请先登录注册