diff --git a/src/pages/mixer/mixer.vue b/src/pages/mixer/mixer.vue index 37169f8..31874e3 100644 --- a/src/pages/mixer/mixer.vue +++ b/src/pages/mixer/mixer.vue @@ -167,6 +167,10 @@ const timerIntervals = ref({}) const dataQueryTimer = ref(null) // 是否正在查询数据 const isQuerying = ref(false) +// 是否已注册监听器 +const hasRegisteredListener = ref(false) +// 数据接收缓冲区(用于处理分包数据) +const receiveBuffer = ref('') // 通道数据 const channels = ref([ @@ -698,6 +702,12 @@ const arrayBufferToString = (buffer) => { const initBluetoothCommunication = () => { if (!deviceId.value) return + // 避免重复注册监听器 + if (hasRegisteredListener.value) { + console.log('蓝牙监听器已注册,跳过重复注册') + return + } + // 监听蓝牙设备连接状态 uni.onBLEConnectionStateChange((res) => { console.log('蓝牙连接状态变化:', res) @@ -710,6 +720,8 @@ const initBluetoothCommunication = () => { }) // 停止数据查询 stopDataQuery() + // 清空接收缓冲区 + receiveBuffer.value = '' } }) @@ -728,33 +740,63 @@ const initBluetoothCommunication = () => { state: true, success: () => { console.log('启用蓝牙数据监听成功') + hasRegisteredListener.value = true // 启动定时查询 startDataQuery() }, fail: (err) => { console.error('启用蓝牙数据监听失败:', err) + hasRegisteredListener.value = false } }) + } else { + hasRegisteredListener.value = true } } // 处理接收到的蓝牙数据 const handleBluetoothData = (buffer) => { try { - // 将 ArrayBuffer 转换为字符串或根据协议解析 + // 将 ArrayBuffer 转换为字符串 const dataStr = arrayBufferToString(buffer) - console.log('解析蓝牙数据:', dataStr) + console.log('收到数据片段:', dataStr) - // 尝试解析为 JSON(根据实际协议调整) + // 处理分包数据:将数据追加到缓冲区 + receiveBuffer.value += dataStr + + // 尝试解析完整的 JSON 数据 try { - const data = JSON.parse(dataStr) - updateChannelFromDevice(data) + // 查找完整的 JSON 对象(以 { 开始,} 结束) + const jsonMatch = receiveBuffer.value.match(/\{[^}]*\}/) + if (jsonMatch) { + const jsonStr = jsonMatch[0] + const data = JSON.parse(jsonStr) + + // 解析成功,更新通道状态 + updateChannelFromDevice(data) + + // 清空已处理的数据(保留剩余未处理的数据) + receiveBuffer.value = receiveBuffer.value.substring(jsonMatch.index + jsonStr.length) + } else { + // 如果缓冲区太大但没有完整 JSON,可能是垃圾数据,清空缓冲区 + if (receiveBuffer.value.length > 200) { + console.warn('缓冲区数据过大且无法解析,清空缓冲区:', receiveBuffer.value) + receiveBuffer.value = '' + } + } } catch (e) { - // 如果不是 JSON 格式,按照其他协议解析 - console.log('非 JSON 格式数据:', dataStr) + // JSON 解析失败,可能是数据还不完整,等待更多数据 + console.log('等待更多数据片段..., 当前缓冲区:', receiveBuffer.value) + + // 如果缓冲区太大,清空它 + if (receiveBuffer.value.length > 200) { + console.warn('缓冲区溢出,清空:', receiveBuffer.value) + receiveBuffer.value = '' + } } } catch (error) { console.error('解析蓝牙数据失败:', error) + receiveBuffer.value = '' // 出错时清空缓冲区 } } @@ -791,10 +833,10 @@ const startDataQuery = () => { // 立即查询一次 queryAllChannelsData() - // 每 2 秒查询一次 + // 每 5 秒查询一次(降低频率,避免蓝牙拥堵) dataQueryTimer.value = setInterval(() => { queryAllChannelsData() - }, 2000) + }, 5000) } // 停止定时查询 @@ -818,13 +860,13 @@ const queryAllChannelsData = () => { channels.value.forEach((channel, index) => { setTimeout(() => { sendBluetoothCommand('query', channel.id) - }, index * 100) // 每个通道间隔 100ms,避免数据冲突 + }, index * 200) // 每个通道间隔 200ms,避免数据冲突 }) // 查询完成后重置标志 setTimeout(() => { isQuerying.value = false - }, channels.value.length * 100 + 500) + }, channels.value.length * 200 + 500) } // 页面卸载 @@ -837,15 +879,42 @@ onUnmounted(() => { // 停止数据查询 stopDataQuery() + // 移除蓝牙监听器 + if (hasRegisteredListener.value) { + uni.offBLECharacteristicValueChange() + uni.offBLEConnectionStateChange() + hasRegisteredListener.value = false + } + // 关闭蓝牙连接(可选,如果需要保持连接则不关闭) if (connected.value && deviceId.value) { + // 先禁用通知 + if (notifyCharacteristicId.value) { + uni.notifyBLECharacteristicValueChange({ + deviceId: deviceId.value, + serviceId: serviceId.value, + characteristicId: notifyCharacteristicId.value, + state: false, + success: () => { + console.log('已禁用蓝牙数据监听') + } + }) + } + + // 关闭连接 uni.closeBLEConnection({ deviceId: deviceId.value, success: () => { console.log('蓝牙连接已关闭') + }, + fail: (err) => { + console.error('关闭蓝牙连接失败:', err) } }) } + + // 清空接收缓冲区 + receiveBuffer.value = '' })