I am using Netty 4.1.0.Final and I am facing an issue where message is not passing through outbound handler. I am posting a sample program where there is one inbound and one outbound handler. Inbound handler uses writeAndFlush in the ChannelHandlerContext and my understanding is that it should forward the message to the first available outbound handler available in the pipeline. Memory Management is ignored for simplicity.
Bootstrap Code
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.localAddress(12021)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new TestHandler1(), new TestOutHandler1());
}
});
ChannelFuture future = bootstrap.bind().sync();
System.out.println("Server Started...");
future.channel().closeFuture().sync();
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
System.out.println("Server Shutdown");
Inbound Handler Code
public class TestHandler1 extends ChannelInboundHandlerAdapter {
private static Log logger = LogFactory.getLog(TestHandler1.class);
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
logger.info("channelRead");
ctx.writeAndFlush(msg);
}
}
Outbound Handler Code
public class TestOutHandler1 extends ChannelOutboundHandlerAdapter {
private static Log logger = LogFactory.getLog(TestOutHandler1.class);
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
logger.info("write");
ctx.writeAndFlush(msg);
}
}
Output
INFO TestHandler1: channelRead
If I change my Inbound Handler as below by doing writeAndFlush() on channel instead of ChannelHandlerContext, I am getting the expected output
Modified Inbound Hanndler
public class TestHandler1 extends ChannelInboundHandlerAdapter {
private static Log logger = LogFactory.getLog(TestHandler1.class);
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
logger.info("channelRead");
ctx.channel().writeAndFlush(msg);
}
}
Output
INFO TestHandler1: channelRead
INFO TestOutHandler1:write
As per Norman's explanation in the below link, I understand as ChannelHandlerContext.write(...) should pass through ChannelOutboundHandlers that are in front of it, which in my case is the only outbound handler.
Norman's Explanation
Let me know if my understanding is wrong or am I missing anything.
Its because you add the ChannelOutboundHandler
before the ChannelInboundHandler
to the ChannelPipeline.
ChannelHandlerContext.writeAndFlush(...)
will start on the point in the ChannelPipeline
where the ChannelHandler
is added. So add the ChannelOutboundHandler
before it will work as expected.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With