`
zhuhui_zj
  • 浏览: 36623 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

netty代码分析(二)--ChannelPipeline

 
阅读更多

一、简介

    ChannelPipeline是事件(event)的通道,它用于组织事件拦截器ChannelHandler。所以本质上,它只是ChannelHandler的一个链表。从I/O端获取的数据将以事件的方式通过ChannelPipeline,并被ChannelUpstreamHandler拦截,最终被程序的业务逻辑处理。要发送的数据通过pipeline被ChannelDowmstreamHandler拦截,并最终到达ChannelSink,由底层nio处理。

二、ChannelHandlerContext

    ChannelHandlerContext是ChannelHandler的包装,使其能以链表的方式存储在ChannelPipeline中:

public class DefaultChannelPipeline implements ChannelPipeline {

    private class DefaultChannelHandlerContext implements ChannelHandlerContext {

        volatile DefaultChannelHandlerContext next;
        volatile DefaultChannelHandlerContext prev;
        private final String name;
        private final ChannelHandler handler;

        public void sendDownstream(ChannelEvent e) {
        		// 找到从prev往前第一个canHandleDownstream的handler
            DefaultChannelHandlerContext prev = getActualDownstreamContext(this.prev);
            if (prev == null) {
                try {
                    // 若已到达pipeline的底端,则交由ChannelSink处理
                    getSink().eventSunk(DefaultChannelPipeline.this, e);
                } catch (Throwable t) {
                    notifyHandlerException(e, t);
                }
            } else {
                DefaultChannelPipeline.this.sendDownstream(prev, e);
            }
        }

        public void sendUpstream(ChannelEvent e) {
            DefaultChannelHandlerContext next = getActualUpstreamContext(this.next);
            if (next != null) {
                DefaultChannelPipeline.this.sendUpstream(next, e);
            }
        }

    ....
  }

    ....
}

三、ChannelPipeline

    ChannelPipeline以链表的方式组织ChannelHandler,提供事件的上下行传输:

public class DefaultChannelPipeline implements ChannelPipeline {

    private volatile Channel channel;
    private volatile ChannelSink sink;
    private volatile DefaultChannelHandlerContext head;
    private volatile DefaultChannelHandlerContext tail;

    public synchronized void addLast(String name, ChannelHandler handler) {
        if (name2ctx.isEmpty()) {
            init(name, handler);
        } else {
            checkDuplicateName(name);
            // 将新加入的handler放置在链表的底端
            DefaultChannelHandlerContext oldTail = tail;
            DefaultChannelHandlerContext newTail = new DefaultChannelHandlerContext(oldTail, 
                                                            null, name, handler);
            oldTail.next = newTail;
            tail = newTail;
            name2ctx.put(name, newTail);
        }
    }

    public void sendUpstream(ChannelEvent e) {
    	//找到从head开始第一个canHandleUpStream的handler
        DefaultChannelHandlerContext head = getActualUpstreamContext(this.head);
        ....
        sendUpstream(head, e);
    }

    void sendUpstream(DefaultChannelHandlerContext ctx, ChannelEvent e) {
        try {
            ((ChannelUpstreamHandler) ctx.getHandler()).handleUpstream(ctx, e);
        } catch (Throwable t) {
            notifyHandlerException(e, t);
        }
    }

    // 以类似方式实现sendDownstream
    ....
}

四、ChannelHandler

    ChannelHandler是事件的拦截器,也是系统主要的扩展点,用户一般通过继承SimpleChannelHandler来实现自己的协议解析方案:

public class SimpleChannelHandler implements 
                         ChannelUpstreamHandler, ChannelDownstreamHandler {

    // 上行事件的分发函数,根据事件的不同,调用不同的方法
    public void handleUpstream(
            ChannelHandlerContext ctx, ChannelEvent e) throws Exception {

        if (e instanceof MessageEvent) {
            messageReceived(ctx, (MessageEvent) e);
        } else if (e instanceof ChildChannelStateEvent) {
            ChildChannelStateEvent evt = (ChildChannelStateEvent) e;
            if (evt.getChildChannel().isOpen()) {
                childChannelOpen(ctx, evt);
            } else {
                childChannelClosed(ctx, evt);
            }
        } else if (e instanceof ChannelStateEvent) {
            ChannelStateEvent evt = (ChannelStateEvent) e;
            switch (evt.getState()) {
            case OPEN:
                if (Boolean.TRUE.equals(evt.getValue())) {
                    channelOpen(ctx, evt);
                } else {
                    channelClosed(ctx, evt);
                }
                break;
            case BOUND:
                if (evt.getValue() != null) {
                    channelBound(ctx, evt);
                } else {
                    channelUnbound(ctx, evt);
                }
                break;
            case CONNECTED:
                if (evt.getValue() != null) {
                    channelConnected(ctx, evt);
                } else {
                    channelDisconnected(ctx, evt);
                }
                break;
            case INTEREST_OPS:
                channelInterestChanged(ctx, evt);
                break;
            default:
                ctx.sendDownstream(e);
            }
        } else if (e instanceof ExceptionEvent) {
            exceptionCaught(ctx, (ExceptionEvent) e);
        } else {
            ctx.sendUpstream(e);
        }
    }

    ....
}

 

分享到:
评论

相关推荐

    netty-4.1源代码

    通过分析Netty的源代码,你可以深入理解其内部机制,比如: - 如何实现高效的内存管理,减少不必要的对象创建和垃圾收集。 - 异步I/O的实现方式,如何利用Java NIO进行非阻塞通信。 - 事件驱动模型是如何工作的,...

    essential-netty-in-action.pdf

    Netty使用了高效的线程模型来最小化资源竞争并提升性能,书中通过多个用例分析了这种模型如何在实际项目中发挥作用。 总体来说,这本书通过丰富的实例和详尽的解释,向开发者提供了Netty编程的全面知识,旨在帮助...

    Netty-入门Netty编码

    Netty 是一个高性能、异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议...通过 TimeServer 和 TimeClient 示例,我们可以逐步掌握 Netty 的基本用法,并为进一步探索其高级特性和源码分析打下基础。

    netty源码深入分析

    《Netty源码深入分析》是由美团基础架构部的闪电侠老师所分享的一系列关于Netty源码解析的视频教程。以下将根据标题、描述、标签以及部分内容等信息,对Netty及其源码进行深入剖析。 ### Netty简介 Netty是基于...

    netty权威指南 第二版 李林锋pdf

    10. **源码分析**:通过对Netty5源码的分析,读者能深入理解Netty内部的工作机制,如如何处理I/O事件、如何调度任务、如何进行数据传输等,这对于优化代码和解决实际问题非常有帮助。 通过阅读《Netty权威指南》第...

    hello netty代码练习

    Netty 是一个高性能、异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能...同时,通过阅读和分析源代码,我们可以更深入地理解 Netty 的事件驱动架构和管道模型,以及如何利用这些特性来优化网络应用性能。

    netty3.2源代码

    为了简化数据在网络中的传输,Netty 提供了一套编解码器接口,可以用于处理各种数据格式,如文本、二进制或自定义协议。例如,ByteToMessageDecoder 和 MessageToByteEncoder 接口分别用于将接收到的字节流解码为...

    netty-code:netty包源码-源码包

    通过分析这些源代码,我们可以学习到许多关于网络编程、并发处理、内存管理以及性能优化的知识。 1. **Netty的基本架构** Netty采用了反应式编程模型,基于事件循环(EventLoop)和异步I/O(NIO)设计。它将复杂的...

    netty-source-analysis-learning-sample-material:netty原始码学习引用资料-源码资源

    这个“netty-source-analysis-learning-sample-material”压缩包文件提供了学习和分析Netty源码的参考资料,帮助开发者深入理解其内部机制。Netty 的设计思想是将复杂的网络编程简化,提供了一种高效、灵活且强大的...

    netty权威指南第二版随书示例源码

    这本书《Netty 权威指南》第二版是深入理解和掌握 Netty 的重要资源,它提供了丰富的示例代码来解释 Netty 的核心概念和实际应用。 Netty 的设计目标是提供一个高效、灵活且易于使用的网络编程框架,使得开发者可以...

    Netty源码解析-服务启动过程.pdf

    #### 二、服务启动过程分析 Netty的服务启动过程涉及到多个核心组件和步骤,下面我们通过一个简单的Netty服务器启动代码示例来进行详细的源码解析。 ##### 1. **初始化线程池** 首先,我们需要初始化两个线程池:...

    Netty权威指南pdf+源代码

    Netty的源代码分析是学习过程中的重要环节。"nettyBookSourceV2.zip"包含的源代码,可以帮助读者深入理解Netty框架的内部机制,如Channel、EventLoop、Pipeline、Handler等核心组件的工作原理。通过对这些源代码的...

    netty学习教程

    #### 二、Netty的核心特性 - **异步非阻塞I/O**:通过利用NIO(New IO),Netty实现了高效的非阻塞I/O操作。 - **事件驱动模型**:基于事件驱动的设计模式,使得开发者可以更加灵活地处理网络事件。 - **高度可配置...

    Netty权威指南第二版源码

    4. **Pipeline和Handler**:Netty的ChannelPipeline是处理链的概念,每个Handler负责一部分业务逻辑。源码揭示了它们如何协同工作,以及如何动态添加、删除Handler以实现灵活的协议处理。 5. **协议支持**:Netty...

    netty视频详解(90节大长篇)

    #### 五、Netty 代码实战与源码剖析 - **实战演练**:通过具体的案例来演示如何使用Netty开发实际的应用程序。 - **源码分析**: - **初始化过程**:分析如何创建Channel、EventLoop等组件,并配置ChannelPipeline...

    demo.rar netty代码例子

    Netty 是一个高性能、异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。这个“demo.rar”压缩包包含了基于 ...通过分析和运行这些代码,我们可以深入理解 Netty 的工作原理和实际应用。

    netty-learning学习Java源代码.zip

    5. **Pipeline**:Netty 的 ChannelPipeline 是一种责任链模式的实现,每个ChannelHandler都可以处理或转发接收到的事件,允许自定义协议处理流程。 6. **易于扩展**:Netty 提供了丰富的协议支持,如TCP、UDP、...

    RGP-NETTY:死磕NETTY原始码-NETTY原始码深度解析

    "死磕NETTY原始码-NETTY原始码深度解析"这个主题,旨在深入理解Netty的内部工作机制,剖析其源代码,从而更好地掌握和利用这个强大的框架。 首先,Netty的核心在于其非阻塞I/O模型,基于Java NIO(Non-blocking ...

    netty-test.zip

    通过分析源代码,你可以了解如何将 protobuf 的序列化和反序列化集成到 Netty 的事件驱动模型中,以及如何有效地处理网络通信中的数据包。这有助于你构建自己的高效、可靠的网络服务,特别是在处理大量并发连接和大...

Global site tag (gtag.js) - Google Analytics