RxAndroidBle 等待客户端响应

RxAndroidBle waiting for client response

我正在将纯 Android BLE 库转换为使用 RxAndroidBle,但遇到了一些障碍。

库当前打开连接,读取特征,并检查它是否已加密。如果是,它会继续读取接下来的几个特征。但是,如果它未加密,它会向客户端发出回调,告诉他们传递加密密钥(客户端负责生成此密钥或从服务器获取它)。密钥传入后,库会将其写入设备,然后像加密设备一样继续运行。

目前在 RxAndroidBle 中,我正在建立连接,读取特征,然后关闭连接。然后,如果它是加密的,则再次建立连接并读取其他特征。如果没有,则触发回调,然后在客户端回复后建立连接。

public void connect() {
    connectionDisposable = bleDevice.establishConnection(false)
            .flatMapSingle(rxBleConnection -> rxBleConnection.readCharacteristic(ENCRYPT_CHARACTERISTIC_UUID))
            .subscribe(bytes -> {
                if(isEncrypted(bytes))
                    encryptedConnect();
                else
                    listener.onKeyNeeded();
            }, this::onError);
}

public void setKey(byte[] key) {
    unencryptedConnect();
}

private void encryptedConnect() {
    connectionDisposable = bleDevice.establishConnection(false)
            .flatMapSingle(rxBleConnection -> Single.zip(
                    rxBleConnection.readCharacteristic(A_CHARACTERISTIC_UUID),
                    rxBleConnection.readCharacteristic(B_CHARACTERISTIC_UUID),
                    rxBleConnection.readCharacteristic(C_CHARACTERISTIC_UUID),
                    DataModel::new))
            .subscribe(this::processData, this::onError);
}

private void unencryptedConnect() {
    connectionDisposable = bleDevice.establishConnection(false)
            .flatMap(rxBleConnection -> rxBleConnection.writeCharacteristic(ENCRYPT_CHARACTERISTIC_UUID)
                .flatMapSingle(bytes -> Single.zip(
                        rxBleConnection.readCharacteristic(A_CHARACTERISTIC_UUID),
                        rxBleConnection.readCharacteristic(B_CHARACTERISTIC_UUID),
                        rxBleConnection.readCharacteristic(C_CHARACTERISTIC_UUID),
                        DataModel::new))
            )
            .subscribe(this::processData, this::onError);
} 

我对 RxJava 完全陌生,但这种连接和重新连接的方法似乎忽略了反应式设计的全部要点。有没有人能给我指出正确的方向,告诉我如何为这个用例正确利用 Rx。即,如何在一个流中等待不同的 observable 发出(客户端对回调的回复),以及如何根据上游结果更改流的路由(根据加密状态更改下一个操作)。理想情况下,无需更改客户端代码,因为库已经部署在一些第 3 方应用程序中。

谢谢。

首先,我看不到您通过处置 connectionDisposable 关闭任何连接的位置。在您执行此操作或设备断开连接之前,连接将一直存在。

您想要的也许可以通过将您的第一个连接保存在 RxBleConnection 类型的变量中来实现。在 .flatMapSingle() 之前插入 .doOnNext( connection -> savedConnection = connection )。然后使用 savedConnection 进行后续操作,而不是建立一个新的。

完成后不要忘记处置。也应该 null savedConnection 以避免尝试使用死连接。