AUTO_READ 在 netty SimpleChannelInboundHandler 中的正确用法
correct usage of AUTO_READ in netty SimpleChannelInboundHandler
我正在将代码从 netty 3.8 版本迁移到 netty 4.1
我使用 netty 使用 http 服务器,下面是 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();
}
}
}
下面是通道处理代码
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();
}
}
我在 HTTPServer 中设置了 AUTO_READ 选项 false,如前所述 ,之后频道消息未在 channelHandler 中处理,如此处所述
.
所以,我手动调用了通道读取。
ChannelOption.AUTO_READ 在此代码中是否得到正确处理?
我认为您在 channelRead0(...)
中收到请求后想再次致电 ctx.read()
。如果您不调用它,您将不会再收到任何请求,这很可能不是您想要的。
此外,您很可能希望将 ctx.channel().read()
替换为 ctx.read()
,这样您就可以开始让当前处理程序处理出站事件,而不是让它流过整个管道(如果有的话)是触发读取的处理程序之后的任何其他处理程序)。
我正在将代码从 netty 3.8 版本迁移到 netty 4.1 我使用 netty 使用 http 服务器,下面是 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();
}
}
}
下面是通道处理代码
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();
}
}
我在 HTTPServer 中设置了 AUTO_READ 选项 false,如前所述
所以,我手动调用了通道读取。 ChannelOption.AUTO_READ 在此代码中是否得到正确处理?
我认为您在 channelRead0(...)
中收到请求后想再次致电 ctx.read()
。如果您不调用它,您将不会再收到任何请求,这很可能不是您想要的。
此外,您很可能希望将 ctx.channel().read()
替换为 ctx.read()
,这样您就可以开始让当前处理程序处理出站事件,而不是让它流过整个管道(如果有的话)是触发读取的处理程序之后的任何其他处理程序)。