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