Ionic BLE发送超20字节失败求助:分段传输仍无效
Ionic BLE Native 发送超过20字节数据失败的解决办法
你碰到的这个问题在BLE开发里真的挺常见——BLE单包默认Payload大多是20字节,不管是无响应发送还是分段传输没成功,大概率是代码里踩了几个容易忽略的小坑,咱们一步步来解决:
先揪出你现有代码里的问题
字符串转Buffer的方式错误
你用newSend[i].buffer来获取Buffer,但普通字符串的buffer属性并不是BLE写入需要的ArrayBuffer类型,这会导致设备根本识别不了你发送的数据,自然会失败。异步循环的陷阱
ble.write是异步Promise操作,用普通for循环同步执行的话,会导致多个写入请求同时发起,BLE栈根本处理不过来,很容易出现丢包或者请求失败的情况。
修正后的完整解决方案
第一步:实现正确的字符串转ArrayBuffer工具函数
BLE设备只认标准的ArrayBuffer类型数据,所以先写个工具函数做转换:
stringToArrayBuffer(str) { const encoder = new TextEncoder(); // TextEncoder会把字符串转成Uint8Array,再转成ArrayBuffer return encoder.encode(str).buffer; }
第二步:用异步循环控制分段发送顺序
因为BLE写入需要等待上一包确认后再发下一包,所以必须用async/await来确保发送顺序,避免并发请求:
async sendLargeBLEData(deviceId, serviceUuid, charUuid, inputText) { // 按19字节分段(你原来的逻辑,也可以根据设备MTU调整,比如20字节) const chunkSize = 19; const dataChunks = []; // 拆分字符串为多个分段 for (let i = 0; i < inputText.length; i += chunkSize) { dataChunks.push(inputText.slice(i, i + chunkSize)); } // 逐包发送,等待每一包写入完成再发下一包 for (const chunk of dataChunks) { const sendBuffer = this.stringToArrayBuffer(chunk); try { await this.ble.write(deviceId, serviceUuid, charUuid, sendBuffer); console.log(`第${dataChunks.indexOf(chunk)+1}包发送成功:`, chunk); } catch (error) { console.error(`第${dataChunks.indexOf(chunk)+1}包发送失败:`, error); // 这里可以加重试逻辑,比如失败后重试2次 throw error; // 抛出错误让上层处理 } } console.log('所有分段数据发送完成!'); }
第三步:调用分段发送方法
把你原来的代码替换成这个调用(注意要在async函数里调用):
// 假设bID、bService、bCharacteristic是你已获取的设备、服务、特征UUID try { await this.sendLargeBLEData(bID, bService, bCharacteristic, this.myInput); } catch (err) { console.error('数据发送失败:', err); }
额外优化建议
- 协商更大的MTU:有些BLE设备支持更大的MTU(比如512字节),你可以先调用
await this.ble.requestMtu(bID, 512)来协商更大的MTU,这样能减少分段次数,提升发送效率。 - 无响应写入的正确用法:如果要用
ble.writeWithoutResponse,不要一次性发所有分段,也要控制发送间隔,避免BLE栈缓存溢出导致丢包。 - 增加重试机制:对每一包发送失败的情况,可以增加2-3次重试逻辑,避免因为临时信号波动导致整体发送失败。
内容的提问来源于stack exchange,提问作者Haim
相关产品推荐
相关产品推荐

