揭秘Netty之——pipeline的设计与使用

责任链模式,相信大家都不陌生。tomcat、spring等各种开源产品中都有大量使用。

责任链设计模式抽象

如上图所示,责任链工程实现中,本质上是维护了一个链表或者数组,以及当前执行位置的索引currentIndex,每次调用责任链的doFilter()方法时,就会基于currentIndex执行下一个Filter。

Netty中PipeLine的设计

通过这个类图也可以大致看出netty中pipeline的设计也是采用了责任链模式,ChannelHandler外包装了一层ChannelHandlerContext,ChannelHandlerContext通过head、tail的设计可以组成一个链表,外部调用通过ChannelPipeLine作为入口,首先调用的就是ChannelHandlerContext的head,然后通过ChannelHandlerContext的next方法依次调用链表中的其他ChannelHandler。

整个实现的伪代码如下所示。

——>ChannelHandlerContext#fireChannelActive
——>Handler#channelActive(ChannelHandlerContext context){
    
    doSth();
    ctx#next()
}

ChannelHandler解读

Netty中channelHandler分为outboundHandler与inboundHandler,整个ChannelHandler按照先写后读的顺序依次执行,outboundHandler——>write——read——>inboundHandler。

例如,当某个pipeline添加handler如下,则

对于inbound的执行顺序为:1,2,3,4,5

对于outbound的执行顺序为:5,4,3,2,1

p.addLast("1", new InboundHandlerA());
p.addLast("2", new InboundHandlerB());
p.addLast("3", new OutboundHandlerA());
p.addLast("4", new OutboundHandlerB());
p.addLast("5", new InboundOutboundHandlerX());

当某个channelHandler被添加到channelPipeline之后,会自动执行该handler的handlerAdded方法。handlerAdded是handler被添加之后执行的第一个方法,也是必须要第一个执行的方法。如果handlerAdded没有被执行,handler的其他方法是无法被执行的。当调用链到来时,该handler会被自动跳过,执行下一个handler。整个执行流程如下所示。

添加ChannelHandler——>执行ChannelHandler#handlerAdded——>ChannelHandler#doSth——>fireNextChannelHandler——>

常用ChannelHandler

1)ChannelInitializer:用于当channel注册到EventLoop之后,快速初始化Channel,其原理就是ChannelInitializer本身也是个ChannelHandler,当ChannelInitializer触发HandlerAdded方法时,就会调用initChannel方法,initChannel方法是可以被重写的,用户可以自定义各种handler。

2)ServerBootstrapAcceptor:该handler主要用在ServerChannel端,用于accept新的客户端连接,并将新创建的childChannel注册到ChildEventLoop中

3)SimpleChannelInboundHandler:继承该类,可以快速实现用于处理某种类型的消息,比如快速实现处理String类型的消息等

总结一下,netty编程过程中,主要流程就是创建channel——>配置channel的pipeline——>注册channel到eventloop——>建立连接开始IO操作


更多精彩内容,欢迎关注

知乎:https://www.zhihu.com/people/mei-an-63

CSDN:https://blog.csdn.net/qq_42672856​

微信:

猜你喜欢

转载自blog.csdn.net/qq_42672856/article/details/115878018