Netty专栏

Netty关键组件ChannelHandler、ChannelP

2019-08-18  本文已影响0人  千淘萬漉

一、ChannelHandler接口

ChannelHandler 为 Netty 中最核心的组件,它充当了所有处理入站和出站数据的应用程序逻辑的容器。ChannelHandler 主要用来处理各种事件,这里的事件很广泛,比如可以是连接、数据接收、异常、数据转换等。

ChannelHandler 有两个核心子类 ChannelInboundHandler 和 ChannelOutboundHandler,其中 ChannelInboundHandler 用于接收、处理入站数据和事件,而 ChannelOutboundHandler 则相反。Handler用适配器模式的Adapter对Handler接口进行了空实现,类图关系如下:

ChannelHandler类图

1.Channel的生命周期

1.ChannelHandler的生命周期

ChannelHandler被添加到ChannelPipeline中或者被从ChannelPipeline中移除时将调用下列操作:

2.ChannelInboundHandler 接口<重点>

ChannelInboundHandler接口处理入站事件和入站数据,提供的事件方法如下图:

image

当某个ChannelInboundHandler 的实现重写channelRead()方法时,它要负责显式地释放与池化的ByteBuf 实例相关的内存,Netty 为此提供了一个实用方法ReferenceCount-Util.release()。当然还有一个更加简单的方式是使用Simple-ChannelInboundHandler,SimpleChannelInboundHandler会自动释放资源。

@Sharable
public class DiscardHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
    ReferenceCountUtil.release(msg);
}

3.ChannelOutboundHandler 接口

出站数据和事件将由ChannelOutboundHandler处理。ChannelOutboundHandler大部分方法都需要一个ChannelPromise参数,以便在操作完成时得到通知。

image

4.ChannelHandler的Adapter适配器

有一些适配器类可以将编写自定义的ChannelHandler所需要的努力降到最低限度,因为它们提供了定义在对应接口中的所有方法的默认实现,因为有时会忽略那些不感兴趣的事件,所以Netty提供了抽象基类ChannelInboundHandlerAdapterChannelOutboundHandlerAdapter

image

ChannelHandlerAdapter 还提供了实用方法isSharable()。如果其对应的实现被标注为Sharable,那么这个方法将返回true,表示它可以被添加到多个ChannelPipeline。

二、ChannelPipeline 接口

每一个新创建的Channel 都将会被分配一个新的ChannelPipeline。这项关联是永久性的;Channel 既不能附加另外一个ChannelPipeline,也不能分离其当前的。

  1. ChannelPipeline本质上是ChannelHandler链的容器
  2. ChannelHandler是处理Channel上的入站和出站事件的代码。
  3. ChannelHandler对象接收事件触发并执行实现的业务逻辑,接着传递给链中的下一个ChannelHandler处理
image
ChannelPipeline pipeline = null ;
ServerHandller firstHandller = new ServerHandller();
pipeline.addLast("handler1", firstHandller);
pipeline.addLast("handler2", new ServerHandller());
pipeline.addLast("handler3", new ServerHandller());
pipeline.remove("handler2");
pipeline.remove(firstHandller);
pipeline.replace("handler3", "newHandler", firstHandller);
//返回和 ChannelHandler 绑定的 ChannelHandlerContext
pipeline.context("newHandler");
pipeline.get("newHandler");

ChannelHandler可以使用@Sharable注解标注,可以将一个ChannelHandler绑定到多个ChannelPipeline链中,也就绑定到多个ChannelhandlerContext,但需注意线程安全!!!

总结:ChannelPipeline保存了与Channel相关联的ChannelHandler,ChannelPipeline可以根据需要,通过添加或者删除ChannelHandler来动态地修改

三、ChannelHandlerContext接口

ChannelHandlerContext代表了ChannelHandler和ChannelPipeline之间的关联,每当ChannelHandler添加到ChannelPipeline中时,都会创建ChannelHandlerContext。

1.压缩事件源,如果这个对象确认不需要经过其他 outBound 类型的 handler 处理,就使用这个方法。

ctx.writeAndFlush() 

2.传递事件源,如果需要把ctx对象往前进行传播,当前创建的对象需要经过后面的 outBound 类型的 handler,那么就调用此方法。

ctx.channel().writeAndFlush()

参考引用:


Netty基础:细说ChannelHandler和ChannelPipeLine
Netty专栏 ——— ChannelHandler和ChannelPipelin

上一篇 下一篇

猜你喜欢

热点阅读