Netty中ChannelHandler的生命周期

在使用Netty进行网络编程的时候,一般须要在网络链接的不一样阶段进行相应的操做,好比在链接创建时,客户端向服务端发起认证,在接收到数据时对数据内容进行解析等等。那么,链接的不一样阶段在netty中如何表示呢? 这即是本文讨论的内容,Netty中ChannelHandller的生命周期。java

首先咱们先分析小网络链接的生命周期,链接创建 ---> 数据交互 ---> 链接断开,在数据交互阶段,包括从链接中读取数据和向链接中写入数据。知道了链接的生命周期,就能够按图索骥的在各个阶段进行想要的操做。而在Netty中,网络链接的不一样生命周期均可以经过回调的方式来绑定相应的逻辑,这个回调接口就是ChannelHandler,这里主要咱们以ChannelInboundHandler为例进行分析。在ChannelInboundHandler中定义了以下和生命周期相关的接口:编程

  • channelRegistered
  • channelUnregistered
  • channelActive
  • channelInactive
  • channelRead
  • channelReadComplete

加上在父类``中定义的两个:服务器

  • handlerAdded
  • handlerRemoved

这些回调接口的调用书序是什么呢?咱们经过写一个LifeCycleHandler来看下ChannelInboundHandler的生命周期的顺序。网络

public class LifeCycleInBoundHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRegistered(ChannelHandlerContext ctx) 
            throws Exception {
        out.println("channelRegistered: channel注册到NioEventLoop");
        super.channelRegistered(ctx);
    }

    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) 
            throws Exception {
        out.println("channelUnregistered: channel取消和NioEventLoop的绑定");
        super.channelUnregistered(ctx);
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) 
            throws Exception {
        out.println("channelActive: channel准备就绪");
        super.channelActive(ctx);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) 
            throws Exception {
        out.println("channelInactive: channel被关闭");
        super.channelInactive(ctx);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) 
            throws Exception {
        out.println("channelRead: channel中有可读的数据" );
        super.channelRead(ctx, msg);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) 
            throws Exception {
        out.println("channelReadComplete: channel读数据完成");
        super.channelReadComplete(ctx);
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) 
            throws Exception {
        out.println("handlerAdded: handler被添加到channel的pipeline");
        super.handlerAdded(ctx);
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) 
            throws Exception {
        out.println("handlerRemoved: handler从channel的pipeline中移除");
        super.handlerRemoved(ctx);
    }
}

启动服务器和Client,链接成功后,断开client的链接,Server端输出结果以下:ide

handlerAdded: handler被添加到channel的pipeline
channelRegistered: channel注册到NioEventLoop
channelActive: channel准备就绪
channelRead: channel中有可读的数据
channelReadComplete: channel读数据完成
channelReadComplete: channel读数据完成
channelInactive: channel被关闭
channelUnregistered: channel取消和NioEventLoop的绑定
handlerRemoved: handler从channel的pipeline中移除

从上面结果能够知道,从链接创建到链接断开,handler的生命周期回调接口调用顺序以下:oop

handlerAdded -> channelRegistered 
-> channelActive -> channelRead -> channelReadComplete
-> channelInactive -> channelUnRegistered -> handlerRemoved

下面具体说下每一个回调的具体含义:线程

  1. handlerAdded: 新创建的链接会按照初始化策略,把handler添加到该channel的pipeline里面,也就是channel.pipeline.addLast(new LifeCycleInBoundHandler)执行完成后的回调;
  2. channelRegistered: 当该链接分配到具体的worker线程后,该回调会被调用。
  3. channelActive:channel的准备工做已经完成,全部的pipeline添加完成,并分配到具体的线上上,说明该channel准备就绪,能够使用了。
  4. channelRead:客户端向服务端发来数据,每次都会回调此方法,表示有数据可读;
  5. channelReadComplete:服务端每次读完一次完整的数据以后,回调该方法,表示数据读取完毕;
  6. channelInactive:当链接断开时,该回调会被调用,说明这时候底层的TCP链接已经被断开了。
  7. channelUnREgistered: 对应channelRegistered,当链接关闭后,释放绑定的workder线程;
  8. handlerRemoved: 对应handlerAdded,将handler从该channel的pipeline移除后的回调方法。
相关文章
相关标签/搜索