使用蓝牙时如何设置超时间隔

How Can I set timeout interval when use bluetooth

当我用蓝牙写数据的时候,希望得到回应。但是当外围设备出现问题时,它不会发送通知。我需要设置一个超时间隔来处理这种不良交互。就像我们使用 urlrequest:

    /// Creates and initializes a URLRequest with the given URL and cache policy.
    /// - parameter: url The URL for the request. 
    /// - parameter: cachePolicy The cache policy for the request. Defaults to `.useProtocolCachePolicy`
    /// - parameter: timeoutInterval The timeout interval for the request. See the commentary for the `timeoutInterval` for more information on timeout intervals. Defaults to 60.0
    public init(url: URL, cachePolicy: CachePolicy = .useProtocolCachePolicy, timeoutInterval: TimeInterval = 60.0) {
        _handle = _MutableHandle(adoptingReference: NSMutableURLRequest(url: url, cachePolicy: cachePolicy, timeoutInterval: timeoutInterval))
    }

我怎么做到的

By "when the peripheral goes wrong" - 如果你的意思是外围设备崩溃或停止工作,那么你应该得到一个 BLE 断开连接事件来指示崩溃:

(centralManager:didDisconnectPeripheral:) 

如果不是这种情况,你只是在一段时间后停止接收通知并且 BLE 连接仍然存在,那么就无法判断外设停止发送通知的原因。这样做的原因是没有特定的 "time" 与通知相关联。有些外围设备每 1 秒发送一次通知,有些外围设备每 1 周发送一次通知。一些外围设备会发送有关值更改的通知(例如,如果温度升高 1 度),有些会发送有关用户操作的通知(例如,用户按下按钮)。

唯一的解决方法是,如果您在中央设备中添加一个计时器,那么每次您收到通知时使用:

peripheral(_:didUpdateValueFor:error:)

您可以重置该计时器(如果它正是您希望超时的通知)。然后,如果计时器到期,您就知道您没有按预期及时收到通知,因此您可以标记错误或强制断开连接。这只是一个示例,您可以创建一些变体(例如,在 peripheral(_:didUpdateValueFor:error:) 上设置一个标志,您每 30 秒检查并重置一次).您可以在以下链接中找到有关计时器的更多信息:-

希望对您有所帮助。

这是一个有趣的问题。

检查 CoreBluetooth 后,我发现他们的列表中已经存在超时错误。 https://developer.apple.com/documentation/corebluetooth/cberror/2325746-connectiontimeout

但是只有第一次连接外设才有效

所以我认为,如果你发送了一个请求,但没有得到任何响应,你必须制作自己的计时器管理器。

超时的概念很复杂。你需要为定时器做一个队列,它是 FIFO。每个请求都需要一个 uniqueId,并且必须将其映射到您的预期响应。

例如:

您致电:

  1. 调用以通过 BLE(任何线程)获取健康信息。
  2. 调用以通过 BLE(任何线程)获取高度信息。
  3. 调用以通过 BLE(任何线程)获取健康信息。

您的回复:

  1. 身高信息。
  2. 健康信息。

将请求与响应对应起来后,您会发现缺少一个预期的响应。那么如何知道请求 1 或请求 3 是否缺少响应。这是你的选择。

总而言之,我认为您需要一个队列请求和一个队列预期响应以及一个计时器队列。管理这些队列并不是一个很大的问题。