Java Netty:空闲状态处理程序未显示通道是否空闲

Java Netty:空闲状态处理程序未显示通道是否空闲,java,netty,Java,Netty,我的要求: 我想检测通道是否空闲读取一段时间,并想在此基础上超时。我的Netty客户端正在向1000台服务器发送请求 问题:我的Netty客户端从未显示如果有一段时间的空闲通道,即使我使用的IP总是超时。 我怀疑我没有正确地实现IdleStateHandler。我已尝试减少IdleStateHandler的读取超时,但没有成功。我花了好几个小时才弄明白。任何帮助都将不胜感激。 下面是我的代码: 我的脾气暴躁的客户: public void connect(final InetAddress re

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

问题:我的Netty客户端从未显示如果有一段时间的空闲通道,即使我使用的IP总是超时。 我怀疑我没有正确地实现IdleStateHandler。我已尝试减少IdleStateHandler的读取超时,但没有成功。我花了好几个小时才弄明白。任何帮助都将不胜感激。
下面是我的代码:
我的脾气暴躁的客户:

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

}
我的网络频道初始化器:

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

}
公共类HttpNetCyclientChannelInitializer扩展了ChannelInitializer{
私人最终提供商handlerProvider;
私有最终int超时;
私有int-maxContentLength;
@注入
公共HttpNetCyclientChannelInitializer(提供程序句柄提供程序,
@命名(“readResponseTimeout”)int超时,@Named(“maxContentLength”)int maxContentLength){
this.handlerProvider=handlerProvider;
this.timeout=超时;
this.maxContentLength=maxContentLength;
}
@凌驾
受保护的通道(SocketChannel SocketChannel){
ChannelPipeline PipelineNetCyclientChannel=socketChannel.pipeline();
addLast(“编解码器”,新的HttpClientCodec());
addLast(“idleStateHandler”,新的idleStateHandler(超时,0,0,TimeUnit.毫秒));
addLast(“聚合器”,新的HttpObjectAggregator(maxContentLength));
//get()将提供通道处理程序的新实例
PipelineNetCyclientChannel.addLast(“handler”,handlerProvider.get());
}
}
我的网络频道处理程序

 @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();
             }
         }
     }
}
@ChannelHandler.Sharable
公共类HttpNetCyclientChannelHandler扩展了SimpleChannelInboundHandler{
@凌驾
public void channelActive(ChannelHandlerContext ChannelHandlerContext){…}
@凌驾
受保护的无效channelRead0(ChannelHandlerContext ChannelHandlerContext,HttpObject HttpObject){…}
@凌驾
public void userEventTriggered(ChannelHandlerContext ctx,Object evt)引发异常{
if(IdleStateEvent的evt实例){
IDLESTATEVENT e=(IDLESTATEVENT)evt;
if(e.state()==IdleState.READER\u IDLE){
System.out.println(“空闲通道”);
ctx.close();
}
}
}
}

您可以进行线程转储以确保不阻止EventLoop吗?什么版本的Netty?我无法在Netty 5.0.0.Alpha2上重现您的问题,您是否拥有无法超时的主机ip地址?我在家里尝试了多种设备