2013-11-02 3 views
7
に閉じた後に再接続する最良の方法は何

簡単なシナリオ: 接続がネッティー

  1. SimpleChannelUpstreamHandlerを拡張し、より低いレベルのクラスA

    。このクラスは、メッセージを送信し、応答を受け取るための作業馬です。
  2. システムの他の部分がメッセージの送受信に使用できる最上位のクラスB(同期と非同期の両方をシミュレートできます)。このクラスはClientBootstrapを作成し、パイプラインファクトリを設定し、bootstrap.connect()を呼び出して、最終的にメッセージの送受信に使用するクラスAのハンドル/参照を取得します。何かのように:

    ChannelFuture future = bootstrap.connect(); 
    Channel channel = future.awaitUninterruptibly().getChannel(); 
    

    ハンドラ= channel.getPipeline().get(A.class);私はクラスAで、私は ます。public void channelClosed(ChannelHandlerContext CTX、ChannelStateEventのe)をオーバーライドすることができます知っている

。 リモートサーバがダウンしたときに通知を受けることができます。

チャネルが終了すると、クラスBの元のクラスA参照(上記のハンドラ)はもはや有効ではないため、新しい参照で置き換える必要があります。

理想的には、クラスAに、上記のオーバーライドされたchannelClosedメソッド内でクラスBに通知するメカニズムを持たせて、bootstrap.connectをクラスB内で再度呼び出すことができます。これを行う1つの方法は、クラスAこれを行うには、クラスBの参照をPipelineFactoryに渡してから、PipelineFactoryにBの参照をAに渡す必要があります。

同じことを実現する他の簡単な方法はありますか?チャネルが閉じられたときに通知されますChannelFutureを返しChannel.closeFuture()

おかげで、

答えて

14

。あなたは別の接続を試みることができるように、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. 
     } 
    }); 
} 
+1

作品罰金を私のために、私は複数のスレッドでNioEventLoopGroupを使用する場合を除き:接続試行が最終的に成功するまで

は、おそらくこれを繰り返します。新しいワーカースレッドが各スケジュールで作成されています(プール内の最大まで)古いワーカースレッドは処理されません。 –