2

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");                   
                }

            }
        });
    }
4

2 に答える 2

2

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 のブートストラップはわずかに異なりますが、ロジックは同じです。これも同期、ブロック、および無視InterruptedExceptionです。実際のアプリケーションでは、 を に登録し、ChannelFutureListenerが完了するFutureと通知される場合がありFutureます。

OP編集された質問の後に追加:

ChannelFutureListener通知を受けている があります。接続を再試行する場合は、そのリスナーにブートストラップへの参照を保持させるか、接続の試行が失敗したことをメインスレッドに伝えて操作を再試行させる必要があります。リスナーにそれを行わせる場合 (これが最も簡単な方法です)、無限再帰を防ぐために再試行回数を制限する必要があることに注意してください。これは、Netty ワーカー スレッドのコンテキストで実行されます。再試行を使い果たした場合も、それをメイン スレッドに伝える必要があります。volatile 変数を介してそれを行うことも、オブザーバー パターンを使用することもできます。

非同期を扱うときは、並行して考える必要があります。その特定の猫の皮を剥ぐ方法はたくさんあります。

于 2013-02-21T16:54:31.107 に答える
1

ありがとうブライアン・ローチ。接続された変数は volatile であり、コードまたはさらなる処理の外部でアクセスできます。

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);                                          
                }
            }

        }
    });
于 2013-02-22T14:47:10.660 に答える