我从Observables中包装了来自各种设备的一些传感器输入。 我想取这些传感器值的平均值,因此Zip运算符似乎很合适。现在的问题是,当与其中一台设备的连接失败时,我不希望整个过程中断。标准行为是,如果源给出错误,则所有源都将终止,并且可从zip运算符本身观察到。 此标准行为有两个问题: 1)当一个源给出错误时,其他源将终止,IE将失去连接。然后,延迟操作员必须重新建立此连接,这需要一些时间。我想在移除设备时无缝过渡。 2)在失败的源上执行.onErrorResumeNext()并不是一种选择,因为这又需要一个源。进行Observable.just(0).repeat()是不可接受的,因为在取值的平均值时对0值进行特殊例外并不干净。
我想要实现的行为是无缝地停止监听发出错误的可观察对象,然后继续处理仍然有效的对象。 有人知道如何执行此操作吗?
编辑: 我设法使系统正常运行,但没有达到我想要的方式。通过以下代码段进行说明:
public FusedHeartRateSensor(HeartRateSensor... devices) {
super("FusedHeartRateSensor", IoTType.TYPE_HEART_RATE_SENSOR, new FusedConnector(), devices);
init();
}
private void init() {
Observable.fromIterable(fusedDevices)
.flatMap(hrs -> hrs.monitorConnection())
.subscribeOn(Schedulers.newThread())
.subscribe(
state -> {
//Als iets verandert met de staat van de geconnecteerde toestellen moet
//de deviceChangeObservable op de hoogte gebracht worden
refreshConnectedDevices();
},
throwable -> {
Log.e(TAG, throwable.getLocalizedMessage());
throwable.printStackTrace();
}
);
}
private void refreshConnectedDevices() {
Log.i(TAG, "Refreshing enabled fused devices");
List<HeartRateSensor> devices = fusedDevices.stream()
.filter(Connectable::isConnected)
.collect(Collectors.toList());
deviceChangeObservable.onNext(devices);
}
private Observable<Integer> getMeanObservable(List<Observable<List<Integer>>> observables) {
System.out.println();
return Observable.zip(observables, objects -> getMean(Arrays.stream(objects).map(o -> (List<Integer>) o).filter(l -> !l.isEmpty()).map(this::getMean).collect(Collectors.toList())));
}
还有要求监控的地方...
@Override
public Observable<Integer> monitorHeartRate() {
ReplaySubject<Integer> resultObservable = ReplaySubject.create();
CompositeDisposable disposable = new CompositeDisposable();
deviceChangeObservable.subscribe(
sensors -> {
Log.i(TAG, "Switched to new sources");
getMeanObservable(sensors.stream()
.map(s -> s.monitorHeartRate()
.buffer(1, TimeUnit.SECONDS))
.collect(Collectors.toList()))
.subscribe(
t -> {
resultObservable.onNext(t);
System.out.println();
},
throwable -> {
throwable.printStackTrace();
System.out.println();
}
);
},
throwable -> {
Log.e(TAG, throwable.getLocalizedMessage());
throwable.printStackTrace();
System.out.println();
}
);
return resultObservable;
}
此问题是,当拉链操作器中的传感器发生故障时,拉链中的所有其他可观察物停止。我当前的解决方案是重试连接,并仅使用仍处于连接状态的设备的可观察对象设置可观察到的新zip。问题在于这不是无缝的。我也尝试过使用defer和retry,但这与上面的代码具有相同的结果。