Netty源码解析-pipeline
1、netty如何判断channelHandler的类型
AbstractChannelHandlerContext构造器需要传入时inbound还是outbound处理器
2、添加channelHandler应该遵循什么规则
3、不同的触发方式有什么区别
pipeline的初始化
pipeline在创建Channel的时候被创建,一个channel对应一个pipeline对象,会创建head和tail两大节点组成双向链表。
pipeline的数据结构ChannelHandlerContext,channelHandlerContext继承AttributeMap和ChannelInboundInvoker和ChannelOutboundInvoker
pipeline的两大哨兵head和tail,tail注意处理exception和未处理的消息,属于inbound,head属于outbound,重点channelActive方法,主要时将事件传播和读写操作。
添加和删除channelHandler
添加channelhandler就是先包装成channelHandlerContext,然后添加链表,最后传播添加完成事件。
判断是否重复添加
创建节点并添加列表
回调添加完成事件
删除channelhandler英语场景就是权限验证,第一包是密码,验证成功后就移除authhandler代码如下
package com.xiaofeiyang; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import java.nio.ByteBuffer; /** * @author: yangchun * @description: * @date: Created in 2020-04-12 6:49 */ public class AuthHandler extends SimpleChannelInboundHandler<ByteBuffer> { @Override protected void channelRead0(ChannelHandlerContext ctx, ByteBuffer password) throws Exception { if(pass(password)){ return;ctx.pipeline().remove(this) }else { ctx.close(); } } private boolean pass(ByteBuffer password) { return true; } }
找到节点
链表删除
回调删除事件
事件和异常的传播
何为inbound事件以及ChannelInboundHandler
registed,accept,read,active都是inbound事件
ChannelRead事件的传播
ctx.fireChannelRead()从当前节点开始传播,ctx.channel().pipeline().fireChannelRead()从头节点开始传播,只在inbound中传播。tail也是InboundHandler。Head节点开始传播的时候只负责找到下一个 inboundHnadler,然后后面的决定是否继续传播还是处理。
SimChannelInboundHandler处理器。
帮忙负责是否释放bytebuf和处理传播事件,如果接受
何为outbound事件以及channelOutboundHandler
用户主动发起的动作,读写或者关闭连接
write事件传播
从tail节点往前面传播
异常在pipeline中传播
从inbound和outbound中传播和添加顺序相关,
异常触发链
从head到tail传播,按照添加顺序部分inbound和outbount传播
异常处理器最佳实践
在最后的添加一个异常处理器就会被处理掉