首页 > 解决方案 > correct usage of AUTO_READ in netty SimpleChannelInboundHandler

问题描述

I'm migrating the code from netty 3.8 version to netty 4.1 I use http server using netty and below is the code for HTTP Server

public class SimpleHTTPServer {

      public void start() {
          try {
              ServerBootstrap b = new ServerBootstrap();
              EventLoopGroup bossGroup = new NioEventLoopGroup();
              EventLoopGroup workerGroup = new NioEventLoopGroup();

              b.group(bossGroup, workerGroup)

                      .channel(NioServerSocketChannel.class)
                      .childHandler(new ChannelInitializer<SocketChannel>() {
                          @Override
                          public void initChannel(SocketChannel ch) {
                              ch.pipeline().addLast("codec", new HttpServerCodec());
                              ch.pipeline().addLast("aggregator",
                                      new HttpObjectAggregator(512 * 1024));
                              ch.pipeline().addLast("request",
                                      new SimpleHTTPHandler());
                          }
                      })
                      .option(ChannelOption.SO_BACKLOG, 128)
                      .childOption(ChannelOption.WRITE_BUFFER_WATER_MARK, WriteBufferWaterMark.DEFAULT)
                      .childOption(ChannelOption.AUTO_READ, false)
                      .childOption(ChannelOption.SO_KEEPALIVE, true);

              ChannelFuture f = b.bind(5055).sync();
              f.channel().closeFuture().sync();

          } catch (Exception e) {
              e.printStackTrace();
          }
      }
  }

Below is the channel handler code

public class SimpleHTTPHandler extends SimpleChannelInboundHandler<FullHttpRequest> {

        protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) {
            HttpResponseStatus responseStatus = OK;
            FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, responseStatus, Unpooled.copiedBuffer("My Netty".getBytes()));
            response.headers().add(request.headers());
            response.headers().set(CONTENT_LENGTH, response.content().readableBytes());
            if (isKeepAlive(request)) {
                response.headers().set(CONNECTION, HttpHeaderValues.KEEP_ALIVE);
            }
            ctx.writeAndFlush(response);
        }

        @Override
        public void channelActive(ChannelHandlerContext ctx) throws Exception {
            super.channelActive(ctx);
            ctx.channel().read();
        }
    }

I set AUTO_READ option false in HTTPServer as mentioned here and after that channel messages are not handled in channelHandler as mentioned here Netty ChannelRead method is not getting invoked.

So, I manually invoked the channel read. Is ChannelOption.AUTO_READ handled correctly in this code?

标签: netty

解决方案


I think you are missing to call ctx.read() again after you received the request in channelRead0(...). If you will not call it you will not receive any more requests, which is most likely not what you want.

Also you most likely want to replace ctx.channel().read() with ctx.read() so you start to have the outbound event be processed by the current handler and not have it flow through the whole pipeline (if there would be any more handlers after the handler that triggers the read).


推荐阅读