RxJava使一个观察者与另一个观察者失败

时间:2015-09-12 19:28:25

标签: java tcp reactive-programming rx-java

假设以下情况,该问题的最佳/建议解决方案是什么?

我有两个流,一个代表TCP连接,另一个代表TCP连接的状态。 一旦状态改变(即断开连接),我想重新获取TCP连接。

我最初的想法是拥有这两个流,合并它们并在结果Observable上应用retryWith。第二个流是PublishSubject的一个实例,它为我提供了一种非常方便的失败方法。现在,这个想法部分有效,除了当我在发布者上调用onError()时,连接流(#1)保持订阅/取消订阅,直到超出retryWhen设置的限制为止。

我确信这个问题过去一定已经解决了,你想要保持TCP连接正常运行,我只是不确定如何从这里开始。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:0)

你不需要两个流。只需使用一个。典型的构造将涉及Observable.using()来创建套接字,在该套接字上建立observable并处理关闭套接字然后用retry()链接(通常有延迟)。

答案 1 :(得分:0)

 return Observable.using(new Func0<XMPPTCPConnection>() {
        @Override
        public XMPPTCPConnection call() {
            L.log("creating connection");
            connection = _createConnection();
            return connection;
        }
    }, new Func1<XMPPTCPConnection, Observable<?>>() {
        @Override
        public Observable<?> call(final XMPPTCPConnection connection) {

            try {
                _authenticate(connection, username, password);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

            return Observable.just(connection)
                    .repeatWhen(new RepeatWhenOperator(-1, 1000))
                    .map(new Func1<XMPPTCPConnection, Object>() {
                        @Override
                        public Object call(XMPPTCPConnection connection) {
                            if (!connection.isConnected()) {
                                throw new RuntimeException("Disconnected");
                            }

                            return null;
                        }
                    });
        }
    }, new Action1<XMPPTCPConnection>() {
        @Override
        public void call(XMPPTCPConnection connection) {
            L.log("disposing");
            _disconnect();
        }
    })
            .subscribeOn(Schedulers.io())
            .unsubscribeOn(Schedulers.io())
            .retry();

好的,基于Observable.using(),我已经提出了这个解决方案。它有效,但我对解决方案不满意 - 即每秒轮询连接是否仍然存在。 XMPPTCPConnection为我提供了一个监听器,用于连接何时死亡,这似乎是一个更好的解决方案 - 只是不确定如何合并...

_disconnect()方法实际上意味着断开和处置;它在当前情况下可能是一个糟糕的名称,但导致抛出RuntimeException的断开发生在该系统之外。

任何想法或改进都会受到很大关注!