Правильное использование AUTO_READ в netty SimpleChannelInboundHandler

Я переношу код из версии netty 3.8 в версию netty 4.1. Я использую http-сервер, используя netty, а ниже приведен код для HTTP-сервера

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

Ниже приведен код обработчика канала

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

Я установил для параметра AUTO_READ значение false в HTTP Server, как упомянуто здесь, и после этого сообщения канала не обрабатываются в channelHandler, как упомянуто здесь, метод Netty ChannelRead не вызывается.

Итак, я вручную вызвал канал чтения. Правильно ли обрабатывается ChannelOption.AUTO_READ в этом коде?

1 ответ

Решение

Я думаю, что вам не хватает позвонить ctx.read() снова после того, как вы получили запрос в channelRead0(...), Если вы не будете звонить, вы больше не будете получать запросы, что, скорее всего, не то, что вы хотите.

Также вы, скорее всего, хотите заменить ctx.channel().read() с ctx.read() поэтому вы начинаете обрабатывать исходящее событие текущим обработчиком, а не пропускать его через весь конвейер (если после обработчика, инициирующего чтение, будет больше обработчиков).

Другие вопросы по тегам