RxAndroidBle ждет ответа клиента - PullRequest
0 голосов
/ 25 мая 2018

Я нахожусь в процессе преобразования чистой библиотеки 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 для этого варианта использования.А именно, как ждать в одном потоке другой наблюдаемой для отправки (ответ клиента на обратный вызов) и как изменить маршрут потока на основе результатов восходящего потока (изменить следующее действие на основе состояния шифрования).В идеале, без изменения кода на стороне клиента, поскольку библиотека уже развернута в нескольких сторонних приложениях.

Спасибо.

1 Ответ

0 голосов
/ 26 мая 2018

Прежде всего, я не вижу, где вы закрываете какие-либо соединения, выбрасывая connectionDisposable.Соединение будет сохраняться до тех пор, пока вы не сделаете это или пока устройство не отключится.

То, что вы хотите, может быть достигнуто путем сохранения вашего первого соединения в переменной типа RxBleConnection.Перед .flatMapSingle() вставить .doOnNext( connection -> savedConnection = connection ).Затем используйте savedConnection для последующих операций вместо установки новой.

И не забывайте распоряжаться, когда закончите.Вероятно, также должен иметь значение null savedConnection, чтобы не пытаться использовать неработающее соединение.

...