react-native-ble-plx接收BLE长消息不完整的配置方案咨询
React Native使用react-native-ble-plx接收BLE长消息不完整问题解决
问题说明
开发React Native应用时,使用react-native-ble-plx库接收BLE设备数据,出现无法获取完整消息、仅收到部分内容的问题。已排除发送端故障(其他APP可正常接收完整消息)。当前临时方案是将消息拆分为11段传输,再在代码中拆分对应字段,但希望通过配置实现单条长消息的完整接收。
当前接收代码
//Connect the device and start monitoring characteristics async function connectDevice(device) { device .connect() .then(device => { setConnectedDevice(device); setIsConnected(true); return device.discoverAllServicesAndCharacteristics(); }) .then(device => { // 监听设备断开事件 BLTManager.onDeviceDisconnected(device.id, (error, device) => { setIsConnected(false); }); // 读取初始值 device .readCharacteristicForService(SERVICE_UUID, MESSAGE_UUID) .then(valenc => { setMessage(base64.decode(valenc?.value)); }); // 监听特征值更新 const MAX_MESSAGES = 11; // 最大存储消息数 const messages = {}; // 存储消息的字典 let currentIndex = 0; // 当前存储索引 device.monitorCharacteristicForService( SERVICE_UUID, MESSAGE_UUID, (error, characteristic) => { if (characteristic?.value != null) { const decodedMessage = base64.decode(characteristic?.value); messages[currentIndex] = decodedMessage; // 存储消息 currentIndex = (currentIndex + 1) % MAX_MESSAGES; // 循环更新索引 setVolt(messages[0]); setFre(messages[1]); setFac(messages[2]); setRLC1(messages[3]); setCor(messages[4]); setPot(messages[5]); setPRea(messages[6]); setPApa(messages[7]); setEAct(messages[8]); setERea(messages[9]); setT(messages[10]); } }, 'messagetransaction', ); }); }
消息示例
- 完整消息:
["122.40,60.48,1.40,0.4767,Ind,81.97,151.17,171.94,0.12,0.21,0.0001,0.849 MN,00:01:07"] - 实际收到内容:
["122.40,60.48,1
解决方案
1. 调整MTU(最大传输单元)
BLE默认MTU通常为23字节,长消息会被自动分片,react-native-ble-plx需要手动协商更大的MTU以支持完整消息传输。在设备连接后添加MTU请求:
async function connectDevice(device) { try { const connectedDevice = await device.connect(); setConnectedDevice(connectedDevice); setIsConnected(true); // 协商更大的MTU(建议值512,需根据设备支持情况调整) const mtuResponse = await connectedDevice.requestMTU(512); console.log('实际生效的MTU:', mtuResponse.mtu); await connectedDevice.discoverAllServicesAndCharacteristics(); BLTManager.onDeviceDisconnected(connectedDevice.id, (error, device) => { setIsConnected(false); }); // 读取初始值 const valenc = await connectedDevice.readCharacteristicForService(SERVICE_UUID, MESSAGE_UUID); setMessage(base64.decode(valenc?.value)); // 监听特征值变化,此时可接收完整消息 connectedDevice.monitorCharacteristicForService( SERVICE_UUID, MESSAGE_UUID, (error, characteristic) => { if (characteristic?.value != null) { const decodedMessage = base64.decode(characteristic?.value); // 直接拆分完整消息的字段 const dataFields = decodedMessage.split(','); if (dataFields.length >= 11) { setVolt(dataFields[0]); setFre(dataFields[1]); setFac(dataFields[2]); setRLC1(dataFields[3]); setCor(dataFields[4]); setPot(dataFields[5]); setPRea(dataFields[6]); setPApa(dataFields[7]); setEAct(dataFields[8]); setERea(dataFields[9]); setT(dataFields[10]); } } }, 'messagetransaction', ); } catch (error) { console.error('连接或配置失败:', error); } }
2. 注意事项
- MTU值需与BLE设备协商,设备会返回实际支持的最大值,并非设置多少就生效多少。
- 确保BLE设备的目标特征支持对应MTU的传输,部分设备可能限制MTU上限。
- 若设置MTU后仍存在分片,需手动实现消息拼接逻辑:在monitor回调中缓存分片数据,通过消息结尾标识(如特定字符、长度字段)判断是否收到完整消息,再进行拼接处理。
内容的提问来源于stack exchange,提问作者Eduardo23484
相关产品推荐
相关产品推荐

