Netty5用户手册之六:netty核心之ChannelHandler用法详解

概述

      主要介绍四个主要的核心类:ChannelPipeline、ChannelHandlerContext、ChannelHandler、Inbound VS Outbound(入站和出站)等。netty提供了强大的类来处理输入和输出的数据,通过ChannelHandler可以快速编写出可重用的、高性能的代码程序。下面一一介绍这些核心类的用法:

ChannelPipeline类的用法

       ChannelPipeline类是ChannelHandler实例对象的列表,用于处理或截获通道的接收和发送数据。它提供了一种高级的截取过滤模式(类似serverlet中的filter功能),让用户可以在ChannelPipeline中完全控制一个事件以及如何处理ChannelHandler与ChannelPipeline的交互.
       对于每个新的通道Channel,都会创建一个新的ChannelPipeline,并将器pipeline附加到channel中。一旦连接,channel和它之间的联系就会建立起来。通道Channel不能附加其他的pipeline或与pipeline分离开。
       下图描述了ChannelHandler通道处理器类与pipeline中的io处理关系,一个io操作可以由一个ChannelInboundHandler或ChannelOutboundHandle进行处理,并通过调用ChannelInboundHandler处理入站io或通过ChannelOutboundHandler处理出站IO。
Netty5用户手册之六:netty核心之ChannelHandler用法详解_第1张图片
        如上图,ChannelPipeline是ChannelHandler的一个列表,如果一个入站io事件发生,这个事件会从第一个开始依次通过每里面的channelhandler;如果是一个出站io事件,则会从最后一个开始依次通过channelhandler。
        ChannelPipeline可以动态添加、删除、替换其中的ChannelHandler,这样的机制可以提高灵活性。
        修改ChannelPipeline的方法:
addFirst(...),添加ChannelHandler在ChannelPipeline的第一个位置
addBefore(...),在ChannelPipeline中指定的ChannelHandler名称之前添加ChannelHandler
addAfter(...),在ChannelPipeline中指定的ChannelHandler名称之后添加ChannelHandler
addLast(ChannelHandler...),在ChannelPipeline的末尾添加ChannelHandler
remove(...),删除ChannelPipeline中指定的ChannelHandler
replace(...),替换ChannelPipeline中指定的ChannelHandler

1.	ChannelPipeline pipeline = ch.pipeline();  
2.	FirstHandler firstHandler = new FirstHandler();  
3.	pipeline.addLast("handler1", firstHandler);  
4.	pipeline.addFirst("handler2", new SecondHandler());  
5.	pipeline.addLast("handler3", new ThirdHandler());  
6.	pipeline.remove("“handler3“");  
7.	pipeline.remove(firstHandler);  
8.	pipeline.replace("handler2", "handler4", new FourthHandler());

ChannelHandlerContext类的用法

      每个ChannelHandler被添加到ChannelPipeline中后,都会创建一个ChannelHandlerContext类添加到ChannelHandler中,此context允许ChannelHandler与其他ChannelHandler进行交互,这是对同一个pipeline而言的。io事件通过contxt将事件传入到pipeline中的下一个channelhandler中,如下图:
Netty5用户手册之六:netty核心之ChannelHandler用法详解_第2张图片

ChannelHandler以及子类

      Netty中有3个实现了ChannelHandler接口的类,其中2个是接口(ChannelInboundHandler用来处理入站数据也就是接收数据、ChannelOutboundHandler用来处理出站数据也就是写数据),一个是抽象类ChannelHandlerAdapter类。
      ChannelHandler提供了在它的生命周期内添加或从ChannelPipeline中删除的方法:
      1.handlerAdded:ChannelHandler添加到实际上下文中准备处理事件。
      2.handlerRemoved:将ChannelHandler从实际上下文中删除,不再处理事件。
      3.exceptionCaught:处理跑出的异常。
      这三个方法都需要传递ChannelHandlerContext参数对象,每个ChannelHandler被添加到Channelpipeline时会自动创建ChannelHandlerContext。
      Netty还提供了一个实现了ChannelHandler的抽象类:ChannelHandlerAdapter类。他实现了父类的所有方法,基本上就是传递事件到pipeline中的下一个ChannelHandler直到结束。

ChannelInboundHandler类的用法

       它提供了一些方法来接收数据或Channel状态改变时被调用,下面是一些常用方法:
       1.channelRegistered:ChannelHandlerContext的Channel被注册到EventLoop中。
       2.channelUnregistered:ChannelHandlerContext的channel从eventloop中注销。
       3.channelActive方法:ChannelHandlerContext的channel已被激活。
       4.channelInactive方法:ChannelHandlerContext的channel结束生命周期。
       5.channelRead方法:从当前Channel的对端读取消息。
       6.channelReadComplete方法:消息读取完毕有执行。
       7.userEventTriggered方法:一个用户事件被触发。
       8.channelWritabilityChanned方法:改变通道的可写状态,可以使用Channel.isWritable检查。
       9.exceptionCaught,重写父类ChannelHandler的方法,处理异常.
       Netty提供了一个实现了ChannelInboundHandler接口并继承ChannelHandlerAdapter的类:ChannelnboundHandlerAdapter。它实现了ChannelInboundHandler所有的方法,作用就是处理消息并将消息转发到ChannelPipeline中的下一个channelhandler。ChannelInboundHandlerAdapter的channelRead方法处理完消息后不会自动释放消息,若想自动释放收到的消息,可以使用SimpleChannelInboundHandler.使用ChannelInboundHandler、ChannelInboundHandlerAdapter、SimpleChannelInboundhandler这三个中的一个来处理接收消息,使用哪一个取决于需求;大多数时候使用SimpleChannelInboundHandler处理消息,使用ChannelInboundHandlerAdapter处理其他的“入站”事件或状态改变。

        ChannelInitializer用来初始化ChannelHandler,将自定义的各种ChannelHandler添加到ChannelPipeline中。

ChannelOutboundHandler类的用法

       它用来处理出站数据(写数据),它提供了以下几种方法:
           1.bind方法:channel绑定本地方法。
           2.connect方法:Channel连接操作。
           3.disconnect方法:Channel断开连接。
           4.close方法:关闭Channel。
           5.deregister方法:注销Channel方法
           6.read方法:读取方法,实际是截获ChannelHandlerContext.read
           7.write方法:写操作,实际是通过ChannelPipeline写消息,Channel.flush方法刷新到实际通道中
           8.flush方法:刷新消息到通道。
       它是ChannelHandler的子类,实现了父类的所有方法。一旦请求停止从ChannelPipeline转发参数,则必须得到通知,是因为它所有重要的方法才去ChannelPromise机制。netty提供了它的实现类,ChannelOutboundHanlderAdapter类。
             重要的是要记得释放致远并通知 ChannelPromise ,若 ChannelPromise 没有被通知可能会导致其中一个 ChannelFutureListener 不被通知去处理一个消息。

你可能感兴趣的:(网络编程)