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
以避免尝试使用死连接。
我正在将纯 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
以避免尝试使用死连接。