最近一直在开发通过ble进行设备与App交互的产品。在开发过程中,手机一直作为中央设备,负责主动发起扫描连接,而设备作为边缘设备。需求需要两者发送指令,传输文件。文件的传输就是将设备中的文件拆解成一包一包的数据通过ble发送给App。在设备与App定义了一套通用的协议的基础上,两者的指令发送很正常,因为指令的发送简短而且单一,双方处理没有问题。但是在发送文件时,遇到了严重的丢包问题。当时设置的设备发送数据到App,拆分的数据包大小是180个字节,这在iphone6s上已经达到上限了。但是在发送文件时,App上接受的数据会出现丢包,首先怀疑的是设备端没有将数据发送出来,后来设备端改了发送逻辑,在每一包数据发送之后,在收到底层的发送成功回调之后再发送下一包数据,在这种模式下,App端接受到的数据还是会丢。当时问题很困扰,App端觉得是设备端的问题,设备端觉得是App端的问题。后来我想到了一种场景,在那种场景的启发下,我觉得现在这种场景是之前那种场景的反向。
之前我在做一款AI 语音耳机时,也是通过ble传输实时音频以及进行OTA(固件升级)的。当时在传输OTA数据包时,由于耳机的内存不够,在我一直发送文件包时,耳机会crash,后来固件排查下来由于内存不够,在疯狂发送数据时,把内存撑爆了,导致了耳机的奔溃,最后的解决方案是我对发送的每一包数据都设置了合适的长度外,还在每一包的发送过程中进行sleep,给固件时间去进行处理,这样问题就解决了。
然后我联想到这次的问题,由于不同的手机采用的蓝牙芯片参差不齐,不同的蓝牙芯片的处理能力又不同,所以我怀疑在固件疯狂发送数据到手机上时,根据不同手机的蓝牙芯片的处理能力,会出现丢包的大小也不一样。针对这种怀疑,我们测试了iphone6s,iphonex,iphone11,发现后两台设备的丢包率明显小很多。我们又测试了不同价位的Android手机,也发现低端Android手机的丢包率也明显大于中高端手机。在基于这种测试基础上,提出了解决方案:1.降低每个数据包的大小,2.每个数据包间隔时间发送,这个时间需要测试。在经过测试之后,单纯第一点解决方案和第二点解决方案都不会达到最理想的结果,所以合适的方案就是两者结合,将丢包率降到更低。所以最终的解决方案就是降低每一包的大小的同时,也保证每包数据包的发送间隔,这两者的数据我们是通过测试之后拿到的平衡值,针对不同的固件的蓝牙芯片这个数据可能都是不同的。
兜兜转转了一圈查到了丢包问题的原因,其实这个原因不难想,我跟固件开发当时都觉得是对方处理的问题,导致一直没有从全局去看这个问题,记录一下。