netty - 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?
解决方案
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).
推荐阅读
- c# - 将我的控制器工厂设置为自定义控制器后,我可以使用 DefaultControllerFactory
- css - 如何在asp.net后面的.ashx.cs代码中添加css
- python - Python:列表项集合的所有可能组合
- javascript - Jquery z-index or focus/active bug
- python - 编写python类型注解时处理79个字符的限制
- ios - 用于 iOS 中文本检测的 Firebase MLKit 错误
- tensorflow - 在 Keras 丢失中保护 Tensorflow acos 函数免受 nans 的影响
- angular - 在 Angular 应用中显示非英文文本
- java - 在android中创建HBox或VBox
- jquery - 如何在没有 sinon 的情况下在 Jquery 中测试 ajax 调用