Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Netty Outbound Handler not getting called

Tags:

netty

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.

like image 657
Ramkumar KS Avatar asked Oct 18 '25 20:10

Ramkumar KS


1 Answers

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.

like image 173
Norman Maurer Avatar answered Oct 21 '25 15:10

Norman Maurer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!