2016-11-01 1 views
0

パイプラインの末尾に達した:私のChannelHandlersあるネッティー - exceptionCaught()イベントが発生し、それは私が私のログにこの警告だ

Nov 02, 2016 12:07:20 AM io.netty.channel.DefaultChannelPipeline onUnhandledInboundException 
WARNUNG: An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception. 
java.util.concurrent.TimeoutException 

@Override 
public void initChannel(SocketChannel ch) throws Exception { 
    ch.pipeline().addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4)); 
    ch.pipeline().addLast(new TimeoutHandler(TIME_OUT_SECONDS)); 
    ch.pipeline().addLast(new ServerCommunicationHandler(messageHandler)); 
} 

をマイ最後の15秒間の読み取りがなかった場合、TimeoutHandlerはTimeoutExceptionをスローします。 そして、私の最後のハンドラ、ServerCommunicationHandlerに、私はexeptionCaught機能をオーバーライドしています

@Override 
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { 
    ctx.close(); 
} 

私は右理解していれば、私の最後のハンドラが例外を処理するのでだから、私は、パイプラインの最後に、例外を再スローしません。正しく、それはありませんか?

なぜこの警告が表示されますか?

私は、チャネルが閉じられた後にこれはTimeoutExceptionを投げ、あなたのTimeoutHandlerが原因で発生することができネッティー4.1.6.Final

答えて

1

を使用しています。チャンネルが閉じられると、すべてのChannelHandlerが削除(登録解除)されますが、ChannelHandlerContextにはまだパイプラインへの参照があるため、チャンネルを閉じてctxのイベントを発生させると、ハンドラはイベントをインターセプトします。

私は、単純な/壊れたTimeoutHandlerを書き込むことによって、あなたが見るエラーを再作成することができました:

@RequiredArgsConstructor 
private static class TimeoutHandler extends ChannelInboundHandlerAdapter { 
    private final int timeoutSeconds; 

    @Override 
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception { 
     ctx.executor().schedule(
       // This exception can still be fired once the channel is closed and all handlers removed 
       () -> ctx.fireExceptionCaught(new TimeoutException()), 
       timeoutSeconds, TimeUnit.SECONDS); 
     super.channelRegistered(ctx); 
    } 
} 

は、あなたの代わりに独自のものを書くのネッティーReadTimeoutHandlerを使用して考えがありますか?

自分で本当に書きたい場合は、チャンネルが無効になったときにタイマーをキャンセルしてください。どのようにIdleStateHandler does thisを見ることができます。

+0

あなたの答えをありがとう。タイムアウトに気付くためにタイムアウトハンドラを実装しました。もしチャンネルが開いていなければ。プログラムをデバッグしましたが、例外がスローされたときにチャネルが既に閉じられていました。どうもありがとう – kaiser

関連する問題