Java 在 Netty 中关闭连接后重新连接的最佳方法是什么
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19739054/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What's the best way to reconnect after connection closed in Netty
提问by step-by-step
Simple scenario:
简单场景:
- A lower level class A that extends SimpleChannelUpstreamHandler. This class is the workhorse to send the message and received the response.
A top level class B that can be used by other part of the system to send and receive message (can simulate both Synchronous and Asynchronous). This class creates the ClientBootstrap, set the pipeline factory, invoke the bootstrap.connect() and eventually get a handle/reference of the class A through which to be used to send and receive message. Something like:
ChannelFuture future = bootstrap.connect(); Channel channel = future.awaitUninterruptibly().getChannel();
A handler = channel.getPipeline().get(A.class);
- 扩展 SimpleChannelUpstreamHandler 的较低级别的类 A。这个类是发送消息和接收响应的主力。
可以被系统的其他部分用来发送和接收消息的顶级 B 类(可以模拟同步和异步)。此类创建 ClientBootstrap,设置管道工厂,调用 bootstrap.connect() 并最终获取用于发送和接收消息的类 A 的句柄/引用。就像是:
ChannelFuture future = bootstrap.connect(); Channel channel = future.awaitUninterruptibly().getChannel();
处理程序 = channel.getPipeline().get(A.class);
I know in class A, I can override public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e); so that when the remote server is down, I can be notified.
我知道在 A 类中,我可以覆盖 public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e); 这样当远程服务器关闭时,我可以得到通知。
Since after channel is closed, the original class A reference (handler above) in class B is not valid anymore, so I need to replace it with a new reference.
由于通道关闭后,B 类中的原始 A 类引用(上面的处理程序)不再有效,因此我需要用新引用替换它。
Ideally, I want class A to have a mechanism to notify class B within the above overrided channelClosed method so the bootstrap.connect can be invoked again within class B. One way to do this is to have a reference in class A that reference class B. To do that, I would need to pass class B reference to the PipelineFactory and then have the PipelineFactory pass the reference of B to A.
理想情况下,我希望类 A 有一种机制在上面覆盖的 channelClosed 方法中通知类 B,以便可以在类 B 中再次调用 bootstrap.connect。一种方法是在类 A 中引用类 B . 为此,我需要将 B 类引用传递给 PipelineFactory,然后让 PipelineFactory 将 B 的引用传递给 A。
Any other simpler way to achieve the same thing?
还有其他更简单的方法来实现同样的目标吗?
thanks,
谢谢,
回答by trustin
Channel.closeFuture()
returns a ChannelFuture
that will notify you when the channel is closed. You can add a ChannelFutureListener
to the future in B so that you can make another connection attempt there.
Channel.closeFuture()
返回一个ChannelFuture
会在通道关闭时通知您。您可以将 a 添加ChannelFutureListener
到 B 中的未来,以便您可以在那里进行另一次连接尝试。
You probably want to repeat this until the connection attempt succeeds finally:
您可能希望重复此操作,直到连接尝试最终成功:
private void doConnect() {
Bootstrap b = ...;
b.connect().addListener((ChannelFuture f) -> {
if (!f.isSuccess()) {
long nextRetryDelay = nextRetryDelay(...);
f.channel().eventLoop().schedule(nextRetryDelay, ..., () -> {
doConnect();
}); // or you can give up at some point by just doing nothing.
}
});
}