【问题标题】:Netty: Idle State Handler is not showing if channel is idleNetty:空闲状态处理程序未显示通道是否空闲
【发布时间】:2018-10-09 23:51:09
【问题描述】:

我的要求:
我想检测通道是否空闲读取一段时间,并希望基于此超时。我的 Netty 客户端正在向 1000 个服务器发送请求。

问题:我的 Netty 客户端永远不会显示是否有一段时间的空闲频道,即使我使用的某些 IP 总是会超时。 我怀疑我没有正确实现 IdleStateHandler。我尝试减少 IdleStateHandler 的读取超时,但没有运气。我已经花了几个小时来解决这个问题。任何帮助将不胜感激。
所以,下面是我的代码:
我的 Netty 客户端:

public void connect(final InetAddress remoteAddress){
        new Bootstrap()
            .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, connectionTimeout)
            .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
            .group(eventLoopGroup)
            .channel(NioSocketChannel.class)
            .handler(httpNettyClientChannelInitializer)
            .connect(remoteAddress, serverPort)
            .addListener(new ChannelFutureListener() {
                    @Override
                    public void operationComplete(ChannelFuture future) {
                        future.cancel(!future.isSuccess());
                    }
                });
    }

我的 Netty 频道初始化器:

public class HttpNettyClientChannelInitializer extends ChannelInitializer<SocketChannel> {
    
    private final Provider<HttpNettyClientChannelHandler> handlerProvider;
    private final int timeout;
    private int maxContentLength;

    @Inject
    public HttpNettyClientChannelInitializer(Provider<HttpNettyClientChannelHandler> handlerProvider,
            @Named("readResponseTimeout") int timeout, @Named("maxContentLength") int maxContentLength) {
        this.handlerProvider = handlerProvider;
        this.timeout = timeout;
        this.maxContentLength = maxContentLength;
    }

    @Override
    protected void initChannel(SocketChannel socketChannel) {
        ChannelPipeline pipelineNettyClientChannel = socketChannel.pipeline();
        pipelineNettyClientChannel.addLast("codec", new HttpClientCodec());
        pipelineNettyClientChannel.addLast("idleStateHandler", new IdleStateHandler(timeout,0,0, TimeUnit.MILLISECONDS));
        pipelineNettyClientChannel.addLast("aggregator", new HttpObjectAggregator(maxContentLength));
        //handlerProvider.get() will provide new instance of channel handler
        pipelineNettyClientChannel.addLast("handler", handlerProvider.get());
    }

}

我的 Netty 频道处理程序

 @ChannelHandler.Sharable
    public class HttpNettyClientChannelHandler extends SimpleChannelInboundHandler<HttpObject> {
      @Override
      public void channelActive(ChannelHandlerContext channelHandlerContext){...}

    @Override    
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, HttpObject httpObject){...}
    
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
             if (evt instanceof IdleStateEvent) {
                 IdleStateEvent e = (IdleStateEvent) evt;
                 if (e.state() == IdleState.READER_IDLE) {
                     System.out.println("Idle channel");
                     ctx.close();
             }
         }
     }
}

【问题讨论】:

  • 你能做一个线程转储以确保你不会阻塞 EventLoop 吗?
  • 什么版本的 Netty?
  • 我无法在 Netty 5.0.0.Alpha2 上重现您的问题,您是否有无法超时的主机 IP 地址?我在家里尝试了多种设备

标签: java netty


【解决方案1】:

某些不匹配的 .jar 库会导致此类错误。你检查过版本和兼容性吗?

  • 版本
  • 依赖关系
  • 完成单元测试

https://github.com/netty/netty

-> 测试 -> 检查问题可能是您之前声明的问题?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-10
    • 2016-07-20
    • 1970-01-01
    • 1970-01-01
    • 2012-10-09
    • 2012-10-04
    相关资源
    最近更新 更多