在Netty连接关闭后重新连接的最佳方法是什么

ste*_*tep 7 java netty

简单场景:

  1. 较低级别的A类,它扩展了SimpleChannelUpstreamHandler.这个类是发送消息并收到响应的主力.
  2. 顶级B类,系统的其他部分可以使用它来发送和接收消息(可以模拟同步和异步).此类创建ClientBootstrap,设置管道工厂,调用bootstrap.connect()并最终获得A类的句柄/引用,用于发送和接收消息.就像是:

    ChannelFuture future = bootstrap.connect();
    Channel channel = future.awaitUninterruptibly().getChannel();
    
    Run Code Online (Sandbox Code Playgroud)

    处理程序= channel.getPipeline().get(A.class);

我知道在A类中,我可以覆盖public void channelClosed(ChannelHandlerContext ctx,ChannelStateEvent e); 这样当远程服务器关闭时,我会收到通知.

由于在关闭通道之后,B类中的原始类A引用(上面的处理程序)不再有效,因此我需要用新引用替换它.

理想情况下,我希望类A具有在上面覆盖的channelClosed方法中通知类B的机制,因此可以在类B中再次调用bootstrap.connect.一种方法是在类A中引用引用类B的引用要做到这一点,我需要将B类引用传递给PipelineFactory,然后让PipelineFactory将B的引用传递给A.

任何其他更简单的方法来实现同样的事情?

谢谢,

tru*_*tin 16

Channel.closeFuture()返回一个ChannelFuture会在关闭频道时通知您.您可以ChannelFutureListener在B中添加未来,以便您可以在那里进行另一次连接尝试.

您可能希望重复此操作,直到最后连接尝试成功为止:

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.
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

  • 对我来说很好用,除非我使用超过 1 个线程的 NioEventLoopGroup。每个计划都会创建一个新的工作线程(直到我的池中的最大值)并且旧的工作线程不会被处理,知道为什么吗? (2认同)