2016-11-01 14 views
0

Я получил это предупреждение в моем журнале:Нетти - An() событие 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 

Это мои ChannelHandlers:

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

Мои TimeoutHandler выдает исключение TimeoutException, если не было чтения за последние 15 секунд. И в моем последнем обработчике ServerCommunicationHandler, я переопределить функцию exeptionCaught:

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

Так что, если я понимаю правильно, я не повторно выдать исключение до конца трубопровода, потому что мой последний обработчик обрабатывает исключение правильно, не так ли?

Зачем мне это предупреждение?

Я использую Нетти 4.1.6.Final

ответ

1

Это может быть вызвано вашим TimeoutHandler метание TimeoutException после того, как канал был закрыт. Это может случиться, потому что, как только канал будет закрыт, все ChannelHandlers будут удалены (незарегистрированы), но 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