博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
5. Netty源码分析之ChannelPipeline 和 ChannelHanler
阅读量:5091 次
发布时间:2019-06-13

本文共 2841 字,大约阅读时间需要 9 分钟。

前言:ChannelPipeline和ChannelHandler是类似于Spring拦截器的一种实现,数据在pipeline中传播,每个ChannelHandler处理自己感兴趣的部分。

一、ChannelPipeline

  ChannelPipeline是ChannelHandler的容器,负责ChannelHandler的管理和事件拦截及调度。

1. ChannelPipeline的事件处理

1. 读操作(InBound):NioEventLoop调用ChannelPipeline的fireChannelRead(..)方法,将消息传输到ChannelPipeline中。Channelhandler处理流程:HeadHandler -> ChannelHandler1 -> .. -> ChannelHandlerN -> TailHandler

2. 写操作(OutBound):调用ChannelHandlerContext的write方法发送消息,经过handler处理后,最终被添加到消息发送缓冲区等待刷新和发送。ChannelHandler处理流程:TailHandler -> ChannelHandlerN -> ... -> ChannelHandler1 -> HeadHandler

 

这里提到了InBound 和 OutBound,顾名思义,InBound就是指进来,例如read、accept这些,都是IO操作往内部方向进行的;OutBound就是指出去,例如connect、write、flush这些,都是IO操作往外部方向进行的。

 2. ChannelPipeline源码分析

  ChannelPipeline实际上是一个ChannelHandler管理容器,它的内部维护了一个ChannelHandler的链表和迭代器,可以方便的增删改查ChannelHandler。

我们看一下addBefore方法,这里先后校验了handler不允许多个ChannelPipeline共享、handlerName不能重复、基准handler不能为null,最后把新增的handler放在基准handler之前,最后触发handlerAdded事件。

public final ChannelPipeline addBefore(String baseName, String name, ChannelHandler handler) {    return addBefore(null, baseName, name, handler);}public final ChannelPipeline addBefore(EventExecutorGroup group, String baseName, String name, ChannelHandler handler) {    final AbstractChannelHandlerContext newCtx;    final AbstractChannelHandlerContext ctx;    synchronized (this) {        //Channdler不允许多个ChannelPipeline共享        checkMultiplicity(handler);        // 1. 如果name为空则生成一个name,2.name不允许重复        name = filterName(name, handler);        // 根据basic查询要插入到哪个Handler之前,如果不存在,则抛异常        ctx = getContextOrDie(baseName);        // 创建DefaultChannelHandlerContext对象        newCtx = newContext(group, name, handler);                // 把它加在ctx前面,就是简单的链表插入操作        addBefore0(ctx, newCtx);        // 当注册暂未成功时,添加一个handlerAdded任务,当注册成功时调用        if (!registered) {            newCtx.setAddPending();            callHandlerCallbackLater(newCtx, true);            return this;        }                // 如果当前线程不是EventLoop线程,则放进EventLoop队列中执行handlerAdded        EventExecutor executor = newCtx.executor();        if (!executor.inEventLoop()) {            callHandlerAddedInEventLoop(newCtx, executor);            return this;        }    }    // 执行handlerAdded    callHandlerAdded0(newCtx);    return this;}private static void addBefore0(AbstractChannelHandlerContext ctx, AbstractChannelHandlerContext newCtx) {    newCtx.prev = ctx.prev;    newCtx.next = ctx;    ctx.prev.next = newCtx;    ctx.prev = newCtx;}

二、ChannelHandler

  ChannelHandler类似于Spring的拦截器,负责对IO事件或IO操作进行拦截和处理,它可以选择性的拦截和处理自己感兴趣的事件,也可以透传和终止事件的传递。

  ChannelHandler的实现类很多,这里主要说一下ChannelHandlerAdapter。

  对于大多数的ChannelHandler而言,都会选择性的拦截自己感兴趣的事件,如果直接实现ChannelHandler,就需要写过多与自己无关的方法。而2ChannelHandlerAdapter实现了ChannelHandler所有的方法,但是所有的实现都是透传,我们只需要继承ChannelHandlerAdapter,覆写自己感兴趣的事件即可。

 

转载于:https://www.cnblogs.com/lovezmc/p/11547896.html

你可能感兴趣的文章
面试题题解
查看>>
理财入门类书籍读书笔记
查看>>
插入排序
查看>>
使用idea构建Hibernate5项目
查看>>
JMeter Webservice API测试计划
查看>>
『计算机视觉』物体检测之RefineDet系列
查看>>
MessageBox如何输出整数
查看>>
【置顶】通知:博客永久迁移 (欢迎来新家哦)
查看>>
JSON
查看>>
栈和队列 迷宫求解
查看>>
Java基础 第五章 循环结构(二) 笔记
查看>>
CSS3制作的一款很酷的错位式导航菜单,可用于博客
查看>>
Github C 编译器项目 8cc main函数中用到的 C库函数
查看>>
Java 获取字符串长度 length()
查看>>
JS处理四舍五入函数 toFixed(n)(可取小数点后n位)
查看>>
iOS 开发,工程中混合使用 ARC 和非ARC(转)
查看>>
JavaScript 执行机制
查看>>
Django---csrf_token
查看>>
[翻译]效率低的日子怎么办?
查看>>
设计模式的饕餮盛宴
查看>>