欢迎到专业群( uni-app 官方技术交流群 1 ) 咨询,群中有相关专业的管理员和群友。
关于 uni.writeBLECharacteristicValue 长数据是否需要分包,答案是需要。
根据知识库中的官方文档说明:APP不会对写入数据包大小做限制,但系统与蓝牙设备会限制蓝牙4.0单次传输的数据大小,超过最大字节数后会发生写入错误,建议每次写入不超过20字节。
为什么需要分包?
- 蓝牙协议限制:低功耗蓝牙 (BLE) 4.0 协议规定单次数据包传输的有效载荷(ATT_MTU 默认值)通常为 20 字节。虽然可以通过 MTU 协商增大单次传输量,但不同设备支持度不一,20 字节是最通用和安全的做法。
- 避免写入失败或静默错误:
- iOS 平台:若单次写入数据过长,系统甚至可能不会有任何回调(包括成功或失败),导致你的应用无法获知写入状态。
- Android 平台:超过系统或蓝牙设备限制时,会发生写入错误,例如返回
10008 系统错误或 10007 (property not support) 错误。
如何实现分包发送?
你可以将需要发送的长数据(ArrayBuffer)分割成多个不超过 20 字节的小数据包,然后依次发送。需要注意发送间隔,发送过快可能导致后续包发送失败。
下面是一个基本的分包发送示例:
async function sendDataInChunks(deviceId, serviceId, characteristicId, fullDataBuffer) {
const CHUNK_SIZE = 20;
let offset = 0;
while (offset < fullDataBuffer.byteLength) {
// 1. 分割数据
const chunk = fullDataBuffer.slice(offset, offset + CHUNK_SIZE);
offset += CHUNK_SIZE;
try {
// 2. 发送当前数据包
await uni.writeBLECharacteristicValue({
deviceId,
serviceId,
characteristicId,
value: chunk,
});
console.log(`已发送数据块,偏移量: ${offset}`);
// 3. 添加延迟,避免发送过快导致失败
await new Promise(resolve => setTimeout(resolve, 50)); // 延迟50毫秒
} catch (err) {
console.error('分包发送失败:', err);
// 在这里处理错误,可以选择重试或终止发送
throw err;
}
}
console.log('所有数据块发送完成');
}
本助手使用国产模型,生成代码可能不准确。专业的代码生成需要全球顶尖的AI Coding模型。推荐使用uni-agent
处理发送失败
在分包发送过程中,可能会遇到错误,例如 10007 (property not support) 或 10008 (system error)。这通常是因为前一个写入操作尚未完成,就发起了新的写入请求。常见的处理方式是:
- 添加延时:如上代码所示,在每个包发送成功后,增加一个短暂的延时(例如 50-200ms)。
- 失败重试:在
fail 回调或 catch 块中,可以暂停一小段时间后,重新发送当前失败的这个数据包。这在 ISSUE 系统 211180 中也有开发者提及和实践。
关于 MTU
如果你的蓝牙设备支持,可以在连接后请求增大 MTU(最大传输单元),从而允许单次发送更大的数据包(例如 200 字节以上),这能显著提高传输效率。你可以通过 uni.setBLEMTU 接口进行设置。
总而言之,为了保证兼容性和稳定性,强烈建议在应用层实现分包逻辑,每次写入不超过 20 字节。
1 个回复
Ask小助手 - Ask社区AI助手
关于
uni.writeBLECharacteristicValue长数据是否需要分包,答案是需要。根据知识库中的官方文档说明:APP不会对写入数据包大小做限制,但系统与蓝牙设备会限制蓝牙4.0单次传输的数据大小,超过最大字节数后会发生写入错误,建议每次写入不超过20字节。
为什么需要分包?
10008系统错误或10007(property not support) 错误。如何实现分包发送?
你可以将需要发送的长数据(ArrayBuffer)分割成多个不超过 20 字节的小数据包,然后依次发送。需要注意发送间隔,发送过快可能导致后续包发送失败。
下面是一个基本的分包发送示例:
处理发送失败
在分包发送过程中,可能会遇到错误,例如
10007(property not support) 或10008(system error)。这通常是因为前一个写入操作尚未完成,就发起了新的写入请求。常见的处理方式是:fail回调或catch块中,可以暂停一小段时间后,重新发送当前失败的这个数据包。这在 ISSUE 系统 211180 中也有开发者提及和实践。关于 MTU
如果你的蓝牙设备支持,可以在连接后请求增大 MTU(最大传输单元),从而允许单次发送更大的数据包(例如 200 字节以上),这能显著提高传输效率。你可以通过
uni.setBLEMTU接口进行设置。总而言之,为了保证兼容性和稳定性,强烈建议在应用层实现分包逻辑,每次写入不超过 20 字节。
要回复问题请先登录或注册
公告
更多>相关问题