RxJava使一个观察者与另一个观察者发生故障

RxJava使一个观察者与另一个观察者发生故障,java,tcp,reactive-programming,rx-java,Java,Tcp,Reactive Programming,Rx Java,假设出现以下情况,问题的最佳/建议解决方案是什么 我有两个流,一个代表TCP连接,另一个代表TCP连接的状态。 一旦状态改变(即断开连接),我想重新获得TCP连接 我最初的想法是将这两个流合并,并对结果的可观察对象应用retryWith。第二条流是PublishSubject的一个实例,这给了我一个非常方便的失败方法。现在,这个想法部分有效,除了在发布服务器上调用onError()时,连接流(#1)会一直订阅/取消订阅,直到超出retryWhen设置的限制 我相信这个问题在过去一定已经解决了,如

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

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

我最初的想法是将这两个流合并,并对结果的可观察对象应用retryWith。第二条流是PublishSubject的一个实例,这给了我一个非常方便的失败方法。现在,这个想法部分有效,除了在发布服务器上调用onError()时,连接流(#1)会一直订阅/取消订阅,直到超出retryWhen设置的限制


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

您不需要两条流。就用一个。典型的构造将涉及
可观察。使用()
创建套接字,在该套接字上建立可观察,并处理关闭套接字的操作,然后使用
重试()
链接该套接字(通常延迟)

返回可观察值。使用(new Func0(){
@凌驾
公共XMPPTCPConnection调用(){
L.log(“创建连接”);
连接=_createConnection();
回路连接;
}
},新Func1调用(最终XMPPTCPConnection连接){
试一试{
_验证(连接、用户名、密码);
}捕获(例外e){
抛出新的运行时异常(e);
}
返回可观察。仅(连接)
.repeatWhen(新的RepeatWhenOperator(-11000))
.map(新函数1(){
@凌驾
公共对象调用(XMPPTCPConnection连接){
如果(!connection.isConnected()){
抛出新的运行时异常(“断开”);
}
返回null;
}
});
}
},新行动1(){
@凌驾
公共无效调用(XMPPTCPConnection连接){
L.log(“处置”);
_断开连接();
}
})
.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.重试();
好的,基于Observable.using()我提出了这个解决方案。它可以工作,但我对解决方案不满意,即每秒轮询一次连接是否仍然存在。XMPPTCPConnection为我提供了一个侦听器,当连接断开时,这似乎是一个更好的解决方案-只是不确定如何合并它

_disconnect()方法实际上是指断开连接并进行处理;在当前情况下,它可能是一个糟糕的名称,但导致抛出RuntimeException的断开连接发生在该系统之外


任何想法或改进都将受到极大的赞赏

通常,TCP连接不会自动关闭,除非更高级别的协议需要它关闭。TCP已经有了一些纠错机制,任何它自己无法解决的问题通常都是真正的网络问题。你确定,你不想在这里依赖成熟的低级机制吗?@SebastianS如果出现网络中断,TCP将断开连接。据我所见,在这个特定的实现中,它在网络再次可用后不会重新连接。可观察者如何知道何时重试?你能举个例子吗?\断开连接应该是指连接。我想你是故意漏掉了一些代码。就重复时间部分而言,我没想到会在那里看到。我不能对XMPPTCPConnection发表评论,因为我不熟悉它,但是除了使用延迟重试之外,我还使用了
.timeout
,这样只有当连接处于静默状态时,我们才能在一定时间后再次连接。要做到这一点,只需在最后一次
.retry()
@DaveMoten之前调用
.timeout
,我知道了,我假设您定期收到ping,然后作为一个项目发出;如果ping没有通过,那就意味着连接断开了-我的理解正确吗?ThanksYep可以在.timeout()之后执行ping并将其过滤掉,或者如果连接足够繁忙,则只依赖于正常流量
 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();