当前位置: 首页 > 知识库问答 >
问题:

Netty连接重试次数

亢建木
2023-03-14

在Netty中重试连接

我正在构建一个客户端套接字系统。要求是:第一次尝试连接到远程服务器当第一次尝试失败时,继续尝试,直到服务器联机。

我想知道netty中是否有这样的功能来做这件事,或者我如何最好地解决这个问题。

非常感谢你

这是我正在纠结的代码片段:

protected void connect() throws Exception {

        this.bootstrap = new ClientBootstrap(new NioClientSocketChannelFactory(
                Executors.newCachedThreadPool(),
                Executors.newCachedThreadPool()));

        // Configure the event pipeline factory.
        bootstrap.setPipelineFactory(new SmpPipelineFactory());

        bootstrap.setOption("writeBufferHighWaterMark", 10 * 64 * 1024);
        bootstrap.setOption("sendBufferSize", 1048576); 
        bootstrap.setOption("receiveBufferSize", 1048576);
        bootstrap.setOption("tcpNoDelay", true);
        bootstrap.setOption("keepAlive", true);
        // Make a new connection.
        final ChannelFuture connectFuture = bootstrap
                .connect(new InetSocketAddress(config.getRemoteAddr(), config
                        .getRemotePort()));

        channel = connectFuture.getChannel();
        connectFuture.addListener(new ChannelFutureListener() {

            @Override
            public void operationComplete(ChannelFuture future)
                    throws Exception {
                if (connectFuture.isSuccess()) {
                    // Connection attempt succeeded:
                    // Begin to accept incoming traffic.
                    channel.setReadable(true);
                } else {
                    // Close the connection if the connection attempt has
                    // failed.
                    channel.close();
                    logger.info("Unable to Connect to the Remote Socket server");                   
                }

            }
        });
    }

共有2个答案

诸超
2023-03-14

谢谢布莱恩·罗奇连接的变量是易失性的,可以在代码或进一步处理之外访问。

final InetSocketAddress sockAddr = new InetSocketAddress(
                config.getRemoteAddr(), config.getRemotePort());
    final ChannelFuture connectFuture = bootstrap
            .connect(sockAddr);

    channel = connectFuture.getChannel();
    connectFuture.addListener(new ChannelFutureListener() {

        @Override
        public void operationComplete(ChannelFuture future)
                throws Exception {
            if (future.isSuccess()) {
                // Connection attempt succeeded:
                // Begin to accept incoming traffic.
                channel.setReadable(true);
                connected = true;
            } else {
                // Close the connection if the connection attempt has
                // failed.
                channel.close();                    
                if(!connected){
                    logger.debug("Attempt to connect within " + ((double)frequency/(double)1000) + " seconds");
                    try {
                        Thread.sleep(frequency);
                    } catch (InterruptedException e) {
                        logger.error(e.getMessage());
                    }   
                    bootstrap.connect(sockAddr).addListener(this);                                          
                }
            }

        }
    });
蒙才
2023-03-14

假设netty 3.x,最简单的例子是:

// Configure the client.
ClientBootstrap bootstrap = new ClientBootstrap(
        new NioClientSocketChannelFactory(
                Executors.newCachedThreadPool(),
                Executors.newCachedThreadPool()));


ChannelFuture future = null;

while (true)
{
    future = bootstrap.connect(new InetSocketAddress("127.0.0.1", 80));
    future.awaitUninterruptibly();
    if (future.isSuccess()) 
    {
        break;
    }
}

显然,您希望为设置最大尝试次数等的循环提供自己的逻辑。Netty 4.x 的引导程序略有不同,但逻辑是相同的。这也是同步的,阻塞的,并忽略中断的异常;在实际应用程序中,您可以向未来注册一个频道未来通知,并在未来完成时收到通知。

在OP编辑后添加问题:

您有一个正在收到通知的ChannelFutureListener。如果您想重试连接,您必须让该侦听器持有对引导程序的引用,或者向您的主线程传达连接尝试失败并让它重试操作。如果您让侦听器这样做(这是最简单的方法),请注意您需要限制重试次数以防止无限递归——它是在Netty工作线程的上下文中执行的。如果您再次用尽重试,您需要将其传达回主线程;您可以通过易失性变量来做到这一点,或者可以使用观察者模式。

在处理异步时,您必须同时思考。有很多方法可以剥那只猫的皮。

 类似资料:
  • 我在运行使用Netty的服务时遇到了问题。它启动和工作正常,但只有一次。在此之后,不接受任何连接(它们将立即被删除)。 当我第一次使用(示例端口,随便什么)连接到服务器时,一切正常: 客户端会话: 服务器日志: --编辑2-- 只要连接处于活动状态,服务器就可以正常工作--在关闭连接之前,我可以轻松地交换请求/响应。 不要被IP地址迷惑,这是一个转发到Docker的本地端口,应用程序就是在那里启动

  • 在Netty中创建客户端连接时,我有一个问题。 这里,为什么我们没有一个bind方法,将通道绑定到发起客户端连接的端口(在客户端)?我们唯一需要提供的就是给出服务器地址和端口如下: 这是在客户端还是服务器端创建了一个新的通道?此通道绑定在客户端的哪个端口? 我们在执行服务器端引导时进行绑定,如下所示 我很困惑,不明白客户端从哪个端口向服务器发送数据,使用的是什么通道?

  • 我正在使用SQL服务器与Node.js.当连接首次尝试失败时,Node.js不会重新尝试连接。我正在使用定期尝试,直到它连接。 上面的代码尝试连接,失败并尝试第二次,但不会继续第三次、第四次等。

  • 我刚刚开始学习Netty,想慢慢来真正理解它是如何工作的。我有一个基于独立套接字测试程序的初始用例: 从客户端连接到服务器时,立即发送消息并处理响应 很简单...或者我是这么想的。我已经看了好几天了,不太明白为什么它的表现不如预期。 这是最初的测试程序,它再次简单地连接到远程服务器,并立即向服务器写入字节缓冲区。然后服务器立即发送一个ack响应,该响应被写入控制台。 我用Netty做了同样的测试,

  • 我正在使用netty 4,并利用将协议状态管理等内容与编解码器分开(例如)。这真的很好用——我喜欢管道的单线程(如果需要的话)特性。 我还想管理断开/重新连接。 但是,当“断开连接”时,我想保留那些本来会发送给断开连接的人的消息。我希望这样做的同时仍然使用netty特性(即在持久化之前仍然使用管道中的处理程序进行编码等)。 不过,显然,这个(逻辑)管道的寿命超过了一个通道的寿命(当重新连接发生时,

  • 我有一个关于ClientBootstrap的问题。下面是场景; null 正如您在错误行中看到的,我得到了这个异常:java.nio.channels.ClosedChannelException。我们不能在断开后使用相同的频道吗?。一旦断开,就完成了吗?。我们如何在SimpleChannelHandler中重新创建连接? 感谢进一步的评论:) <<<<<<新方法>>>>> 在SimpleChan