DEV Community

Salad Lam
Salad Lam

Posted on

netty5: Channel, ChannelPipeline and ChannelHandler

This post is based on the source code of netty-5.0.0.Alpha5.

Channel

When making a network connection, new instance will be created.

Channel contains:

  • IP address and port of destination
  • EventLoop instance which serves this channel
  • ChannelPipeline instance which stores series of Channelhandler
  • function of operations can act on it

Channel.pipeline().fireChannelRead(Buffer) will be called when data is read from network layer.

Reference of Channel may be passed into user logic code, for sending reply first call Channel#isActive to check if that channel is active or not. Then call Channel#write or Channel#writeAndFlush.

ChannelPipeline

When creating a new Channel, a new ChannelPipeline instance is also created. On the fly modification of ChannelHandler in ChannelPipeline without affecting other ChannelPipeline is supported (One of the use cases is to switch to TLS session after an unencrypted session is created in StartTLS protocol).

ChannelHandler(s) which handle application logic are added during ChannelPipeline initialization. To use Bootstrap class as example,

Bootstrap b = new Bootstrap();
b.handler(new ChannelInitializer<DatagramChannel>() {
  @Override
  protected void initChannel(DatagramChannel ch) {
    ChannelPipeline p = ch.pipeline();
    p.addLast(new DatagramDnsQueryEncoder())
      .addLast(new DatagramDnsResponseDecoder())
      .addLast(new SimpleChannelInboundHandler<DatagramDnsResponse>() {
        @Override
        protected void messageReceived(ChannelHandlerContext ctx, DatagramDnsResponse msg) {
          try {
            handleQueryResp(msg);
          } finally {
            ctx.close();
          }
        }
      });
  }
});
Enter fullscreen mode Exit fullscreen mode

On ChannelPipeline implementation DefaultChannelPipeline, there is two lists of ChannelHandlerContext.

  • handlers: DefaultChannelHandlerContext list, use for instance lookup
  • head: first element (always HeadHandler) of DefaultChannelHandlerContext double linked list. First ChannelHandler processing bytes from network layer
  • tail: last element (always TailHandler) of DefaultChannelHandlerContext double linked list. First ChannelHandler processing objects from from application

Functions of ChannelHandlers in the chain are run in the same EventExecutor.

ChannelHandler

Code in ChannelHandler can be run in different EventExecutor at the same time. So make sure that the class is thread safe.

A ChannelHandlerContext instance, will be passed as parameter when function of this interface is called. For example

Future<Void> write(ChannelHandlerContext ctx, Object msg);
Enter fullscreen mode Exit fullscreen mode

ChannelHandlerContext contains:

  • Channel
  • ChannelHandler
  • ChannelPipeline

Do not include processing expensive jobs or using blocking functions in any function of ChannelHandler.

When calling Channel#write, message will be go to the beginning of ChannelPipeline. But when calling ChannelHandlerContext#write, message will be go to next ChannelHandler.

Reference

https://www.youtube.com/watch?v=_GRIyCMNGGI

Top comments (0)