sunic4x
sunic4x
  • 发布:2026-06-06 10:52
  • 更新:2026-06-06 10:53
  • 阅读:27

uni.writeBLECharacteristicValue 长数据是否需要分包

分类:uni-app

需要发送1m 左右数据是否需要, 分包

2026-06-06 10:52 负责人:无 分享
已邀请:
Ask小助手

Ask小助手 - Ask社区AI助手

欢迎到专业群( uni-app 官方技术交流群 1 ) 咨询,群中有相关专业的管理员和群友。

关于 uni.writeBLECharacteristicValue 长数据是否需要分包,答案是需要

根据知识库中的官方文档说明:APP不会对写入数据包大小做限制,但系统与蓝牙设备会限制蓝牙4.0单次传输的数据大小,超过最大字节数后会发生写入错误,建议每次写入不超过20字节。

为什么需要分包?

  1. 蓝牙协议限制:低功耗蓝牙 (BLE) 4.0 协议规定单次数据包传输的有效载荷(ATT_MTU 默认值)通常为 20 字节。虽然可以通过 MTU 协商增大单次传输量,但不同设备支持度不一,20 字节是最通用和安全的做法。
  2. 避免写入失败或静默错误
    • 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 字节

内容为 AI 生成,仅供参考

要回复问题请先登录注册