通过无响应发送时,CoreBluetooth数据包丢失

问题描述

在iOS上,某些数据包会通过BLE丢失。

在特征上,我们当然会检查.withoutResponsecanSendWriteWithoutResponse的类型func peripheralIsReady(toSendWriteWithoutResponse peripheral: CBPeripheral)。 文档中也对此进行了说明。

另一方面,如果您将写入类型指定为 CBCharacteristicWriteType.withoutResponse,核心蓝牙尝试 写下价值,但不能保证成功。如果写不 在这种情况下成功,您不会收到通知,也不会收到 错误,指示失败原因。

任何人都知道如何在不切换到withResponse的情况下解决此问题?

解决方法

BLE是一种分布式协议。 总是可能会丢失数据。确保您没有丢失数据的唯一方法是收到一些通知,通知您数据已正确接收(通常称为“ ACK确认”)。实现此目标的标准BLE方法是响应。但是,如果您不想使用标准的ACK方案,则可以自由实施自己的ACK方案。

作为一个例子,您可以在您的中央设备所订阅的外围设备中创建一个“确认”特征。发送写操作时,您将等到收到来自该特征的通知。如果超时后仍未收到通知,则可能是写入已丢失。这样可以在更高的层上重新实现标准的带响应写系统。

我处理的几个BLE协议实际上是串行协议(我们写入特性,并从相同特性读取响应)。我们通常直接在串行协议中实现ACK(例如,返回<msgid>OK),而无需BLE写响应。

另一种解决方案是写入特征,然后从特征中读取以查看其是否已更新,前提是特征是以这种方式对称的(很多不是)。我相当确定,这里没有写缓存会咬你,因为BLE读和写通常不对称,但是在依赖它之前应仔细检查。 (请参阅2019年和2017年的Core Bluetooth WWDC视频。)

与所有分布式系统一样,也永远不可能知道数据丢失。数据可能到达了,并且响应丢失了。这是分布式协议的本质,只是必须要考虑到系统中。这就是为什么可以构建至少一次传递消息 的系统(前提是可以传递),或者构建一个最多传递消息 的系统。一次,但是不可能构建一个可以准确地一次发送消息的系统。

如果您无法控制外围设备,并且不提供任何错误检测机制,那么在中央(电话)端您将无能为力。您必须双方都进行一些合作才能构建容错的分布式协议。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...