`

netty入门

 
阅读更多

1 阻塞IO ,阻塞异步IO,非阻塞异步IO

首先学习netty ,那就必须对阻塞IO ,阻塞异步IO,非阻塞异步IO有一个了解,可以参考https://www.ibm.com/developerworks/cn/linux/l-async/

2 netty的架构

netty吸收了多种协议( FTP,SMTP,HTTP,WebSocket,SPDY,二进制、文本)实现的经验,帮助实现了构建快速构建一个高性能、稳定、以扩展的,基于NIO的客户端、服务端框架,其体系结构如下:



 3 核心类分析

1) EventLoop类

在netty中的体系架构中的位置



 EventLoop是基于current包中的ScheduledExecutorService来做线程调度的:下面是EventLoop的源码分析:

EventLoop

 

public interface EventLoop extends EventExecutor, EventLoopGroup {
    @Override
    EventLoopGroup parent();
}
 eventLoop继承EventLoopGroup,EventLoopGroup的源码如下:

 

EventLoopGroup

 

public interface EventLoopGroup extends EventExecutorGroup {
    /**
     * 下一个事件执行器(EventExcutor)
     */
    @Override
    EventLoop next();

    /**
     * 将一个Channel注册给EventExecutor,返回一个ChannelFuture
     */
    ChannelFuture register(Channel channel);

    /**
     * Channel注册给EventExecutor,ChannelPromise是一个可以写入的ChannelFuture* 返回一个ChannelFuture
     */
    ChannelFuture register(Channel channel, ChannelPromise promise);
}
EventExecutor
public interface EventExecutor extends EventExecutorGroup {

    /**
     * 返回指向自己的引用
     */
    @Override
    EventExecutor next();

    /**
     * 返回父类EventExecutorGroup
     */
    EventExecutorGroup parent();

    /**
     * 判断一个线程是否在ScheduledExecutorService的调度中
     */
    boolean inEventLoop();

    /**
     * 判断一个线程是否在ScheduleExecutorService的调度中
     */
    boolean inEventLoop(Thread thread);
    <V> Promise<V> newPromise();
    <V> ProgressivePromise<V> newProgressivePromise();
    <V> Future<V> newSucceededFuture(V result);
    <V> Future<V> newFailedFuture(Throwable cause);
}
 

 

EventLoop下就有EmbededEventLoop和抽象类SingleThreadEventLoop 
SingleThreadEventLoop

根据字面意思,可以看出管理event的线程是单一的。他的子类有AioEventLoop,LocalEventLoop,NioEventLoop,OioEventLoopSingleThreadEventLoopImp等。 

 

MultithreadEventLoopGroupl

实际上就是SingleThreadEventLoop

详情可以参考:

http://airu.iteye.com/blog/1749331

2) ChannelHandler类

 

public interface ChannelHandler {

    /**
     * Gets called after the {@link ChannelHandler} was added to the actual context and it's ready to handle events.
     */
    void handlerAdded(ChannelHandlerContext ctx) throws Exception;

    /**
     * Gets called after the {@link ChannelHandler} was removed from the actual context and it doesn't handle events
     * anymore.
     */
    void handlerRemoved(ChannelHandlerContext ctx) throws Exception;

    /**
     * Gets called if a {@link Throwable} was thrown.
     *
     * @deprecated  Will be removed in the future and only {@link ChannelInboundHandler} will receive
     *              exceptionCaught events. For {@link ChannelOutboundHandler} the {@link ChannelPromise}
     *              must be failed.
     */
    @Deprecated
    void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception;

    /**
     * Indicates that the same instance of the annotated {@link ChannelHandler}
     * can be added to one or more {@link ChannelPipeline}s multiple times
     * without a race condition.
     * <p>
     * If this annotation is not specified, you have to create a new handler
     * instance every time you add it to a pipeline because it has unshared
     * state such as member variables.
     * <p>
     * This annotation is provided for documentation purpose, just like
     * <a href="http://www.javaconcurrencyinpractice.com/annotations/doc/">the JCIP annotations</a>.
     */
    @Inherited
    @Documented
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @interface Sharable {
        // no value
    }
}
每一个ChannelHandler添加都ChannelPipeline中都需要创建和绑定一个ChannelHandlerContext,如图所示:

 



 ChannelHandlerContext类

 

public interface ChannelHandlerContext
         extends AttributeMap, ChannelPropertyAccess,
                 ChannelInboundInvoker, ChannelOutboundInvoker {

    /**
     * Return the {@link Channel} which is bound to the {@link ChannelHandlerContext}.
     */
    Channel channel();

    /**
     * The {@link EventExecutor} that is used to dispatch the events. This can also be used to directly
     * submit tasks that get executed in the event loop. For more information please refer to the
     * {@link EventExecutor} javadoc.
     */
    EventExecutor executor();

    /**
     * The unique name of the {@link ChannelHandlerContext}.The name was used when then {@link ChannelHandler}
     * was added to the {@link ChannelPipeline}. This name can also be used to access the registered
     * {@link ChannelHandler} from the {@link ChannelPipeline}.
     */
    String name();

    /**
     * The {@link ChannelHandler} that is bound this {@link ChannelHandlerContext}.
     */
    ChannelHandler handler();

    /**
     * Return {@code true} if the {@link ChannelHandler} which belongs to this {@link ChannelHandler} was removed
     * from the {@link ChannelPipeline}. Note that this method is only meant to be called from with in the
     * {@link EventLoop}.
     */
    boolean isRemoved();

    @Override
    ChannelHandlerContext fireChannelRegistered();

    @Override
    @Deprecated
    ChannelHandlerContext fireChannelUnregistered();

    @Override
    ChannelHandlerContext fireChannelActive();

    @Override
    ChannelHandlerContext fireChannelInactive();

    @Override
    ChannelHandlerContext fireExceptionCaught(Throwable cause);

    @Override
    ChannelHandlerContext fireUserEventTriggered(Object event);

    @Override
    ChannelHandlerContext fireChannelRead(Object msg);

    @Override
    ChannelHandlerContext fireChannelReadComplete();

    @Override
    ChannelHandlerContext fireChannelWritabilityChanged();

    @Override
    ChannelHandlerContext flush();
}
 

 

这里的ChannelInboundInvoker接口基本上就是拥有通知Channel上的各种事件的能力,二ChannelOutboundInvoker则是具备了向管道外写数据,连接等功能。注意返回值都是ChannelFuture这就说明这些操作都是异步的。 
总之ChannelOutboundInvoker是Channel,ChannelhandlerContext, ChannelPipeline的父接口。 
对于ChannelHandlerContext来说,基本上就是对传输过程中的各个方面的管理器。包括ChannelHandler的注册销毁等等。 

每个ChannelHander都是有方向性的。这里的方向性,也就是管道中inbound和outbound的意思。所以ChannelHander的两个子接口 ChannelOperationHandler 也就是outbound 和ChannelStateHandler 也就是inbound。围绕着in与out,又催生出子接口 ChannelOutboundHandler 和 ChannelInboundHandler。比较常用的子类:

ChannelInboundHandlerAdapter 和 ChannelOutboundHandlerAdapter

 

public class ChannelInboundHandlerAdapter extends ChannelHandlerAdapter implements ChannelInboundHandler {

    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        ctx.fireChannelRegistered();
    }
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        ctx.fireChannelUnregistered();
    }

    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        ctx.fireChannelActive();
    }

    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        ctx.fireChannelInactive();
    }
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ctx.fireChannelRead(msg);
    }
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.fireChannelReadComplete();
    }

    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        ctx.fireUserEventTriggered(evt);
    }

    public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
        ctx.fireChannelWritabilityChanged();
    }

    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
            throws Exception {
        ctx.fireExceptionCaught(cause);
    }
}
 可以根据自己需要重写对应的方法,(方法的使用,请查阅api),ChannelOutboundHandlerAdapter也类似
ChannelPipeline类
ChannelPipeline的作用看如下图就可以明白了


 Buffer类
netty重写了NIO中的buffer,NIO中的buffer使用起来容易出错,也比较复杂,垃圾回收起来不方便,netty 中的Buffer则解决了这些问题,内存分配算法可以参见:http://en.wikipedia.org/wiki/Buddy_memory_allocation
Bootstrap类
Bootstrap 和 BootstrapServer都是继承AbstractBootstrap
查看AbstractBootstrap的变量定义
    private volatile EventLoopGroup group;
    private volatile ChannelFactory<? extends C> channelFactory;
    private volatile SocketAddress localAddress;
    private final Map<ChannelOption<?>, Object> options = new LinkedHashMap<ChannelOption<?>, Object>();
    private final Map<AttributeKey<?>, Object> attrs = new LinkedHashMap<AttributeKey<?>, Object>();
    private volatile ChannelHandler handler;
 一个事件组,netty是事件驱动的,事件组应该是各种事件的容器;一个Channel工厂,这自然是用来生产Channel的(这里应该有各种管道。比如服务端的和客户端的就不一样) ;SocketAddress是本地地址 options 是这个管道的属性集合 attrs 是属性键集合(这个搞不懂,先放下); ChannelHandler 用于处理管道的各种事件吧。 
具体方法的含义如下:
1, public B group(EventLoopGroup group) 
这个函数简单,设置group,注意如果传入参数为空,或者原先的group不为空都要抛出异常。然后,返回自身 ,注意泛型 B 
2, public B channel(Class<? extends Channel> channelClass) 
这个类用来创建一个Channel实例,使用了ChannelFactory。使用工厂模式推迟具体实例创建到子类中。这里可以看做一个工厂设置 
3, public B channelFactory(ChannelFactory factory) 
2调用了3, 
4,public B localAddress(SocketAddress localAddress) 
绑定本地地址 
5, public B localAddress(int port) 
同样绑定本地地址 
6, public B localAddress(String host, int port) 
同4,5 
7, public  B localAddress(InetAddress host, int port) 
通4,5,6 
8, public <T> B option(ChannelOption<T> option, T value) 
实例化Channel时的参数。如果 value为null,这个option被remove掉。 
9, public <T> B attr(Attribute<T> key, T value) 
实例化Channel后Channel的属性value为null时,attr被remove掉。 
10, public void shutdown() 
这里关闭的是EventLoopGroup 
11, protected void validate() 
这里变protected了,用于同类的参数验证。子类如果复写,需要使用super先调用父类 
12,protected final void validate(ChannelFuture future) 
验证了future不为null,然后调用11, 不可以被复写 
13,public ChannelFuture bind() 
创建一个Channel并且绑定 
14,public B handler(ChannelHandler handler) 
handler不能为null,设置handler 
15,public static boolean ensureOpen(ChannelFuture future) 
确保future中的channel为open状态,否则futrue设置为失败ChannelException 
16,public abstract ChannelFuture bind(ChannelFuture future) 
把Channel绑定到给定的ChannelFactory上。抽象方法,意味着需要具体的Channel 
Bootstrap中多了两个变量
    private static final InternalLogger logger = InternalLoggerFactory.getInstance(Bootstrap.class);

    private volatile SocketAddress remoteAddress;
 BootstrapServer类
    private final Map<ChannelOption<?>, Object> childOptions = new LinkedHashMap<ChannelOption<?>, Object>();
    private final Map<AttributeKey<?>, Object> childAttrs = new LinkedHashMap<AttributeKey<?>, Object>();
    private volatile EventLoopGroup childGroup;
    private volatile ChannelHandler childHandler;
 
    /**
     * Set the {@link EventLoopGroup} for the parent (acceptor) and the child (client). These
     * {@link EventLoopGroup}'s are used to handle all the events and IO for {@link SocketChannel} and
     * {@link Channel}'s.
     */
    public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup) {
        super.group(parentGroup);
        if (childGroup == null) {
            throw new NullPointerException("childGroup");
        }
        if (this.childGroup != null) {
            throw new IllegalStateException("childGroup set already");
        }
        this.childGroup = childGroup;
        return this;
    }
 
  • 大小: 59.4 KB
  • 大小: 69.7 KB
  • 大小: 48.5 KB
  • 大小: 46.4 KB
分享到:
评论

相关推荐

    Netty入门教程文档

    Netty入门教程文档 Netty是Java的网络编程框架,广泛应用于数据采集服务中,本文将对Netty的基本概念和应用进行详细介绍,并将其与ETL技术结合,讲解如何使用Netty进行数据流转和处理。 1. ETL概述 ETL(Extract...

    Netty 入门与实战:仿写微信 IM 即时通讯系统.pdf

    ### Netty 入门与实战:仿写微信 IM 即时通讯系统 #### 一、引言 随着移动互联网技术的飞速发展,即时通讯(IM)应用已成为人们日常生活中不可或缺的一部分。微信作为中国最成功的即时通讯软件之一,其背后的架构和...

    Netty入门与实战:仿写微信IM即时通讯系统

    ### Netty入门与实战:仿写微信IM即时通讯系统 #### 一、引言 随着移动互联网技术的飞速发展,即时通讯(IM)系统已成为人们日常生活中不可或缺的一部分。微信作为国内最受欢迎的即时通讯软件之一,其高效稳定的通信...

    Netty 入门与实战:仿写微信 IM 即时通讯系统.rar

    Netty 入门与实战:仿写微信 IM 即时通讯系统,掘金小册子,netty教程。章节齐全无缺失,排版非常不错。 1.仿微信IM系统简介 1 2.Netty是什么? 2 3.服务端启动流程 8 4.客户端启动流程 11 5.实战:客户端与服务端双向...

    Netty 入门与实战:仿写微信 IM 即时通讯系统.zip

    《Netty 入门与实战:仿写微信 IM 即时通讯系统》是一本深入浅出的教程,旨在帮助读者掌握使用Netty构建高效、稳定、高性能的即时通讯系统的方法。通过模仿微信IM的实现,本书将理论知识与实践案例相结合,使读者...

    netty入门到精通.txt

    根据提供的文件信息“netty入门到精通”,我们可以深入探讨Netty框架的相关知识点,包括其基本概念、核心组件、应用场景以及如何逐步掌握这项技术。 ### Netty框架简介 Netty是一款高性能、异步事件驱动的网络应用...

    Netty 入门与实战:仿写微信 IM 即时通讯系统

    在本文中,我们将深入探讨Netty框架,并通过实战项目——仿写微信IM即时通讯系统,来深入了解其在高性能网络应用中的应用。Netty是Java领域中一个高效的异步事件驱动的网络应用程序框架,它为快速开发可维护的高性能...

    netty入门进阶之前

    文件"72-第2章_20-netty入门-jdk-future-480P 清晰-AVC.Cover.jpg"、"73-第2章_21-netty入门-netty-future-480P 清晰-AVC.Cover.jpg"和"74-第2章_22-netty入门-netty-promise-480P 清晰-AVC.Cover.jpg"详细解释了...

    Netty 入门与实战

    Netty 是一个高性能、异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。这个框架在Java领域广泛应用于构建高并发、低延迟的网络应用,如分布式系统、游戏服务器、金融交易系统等。...

    netty入门示例工程

    本工程采用maven+netty4.1.0+PrefixedStringDecoder+json技术,包括客户端和服务端。先运行服务端SampleServer,再去等客户端SampleClient。示例中发的是心跳包,其中消息格式定义为msgType + msgNo + content(json...

    netty入门案例.zip

    这个“netty入门案例.zip”文件提供了一个简单的 Netty 应用示例,旨在帮助初学者快速理解并掌握 Netty 的基本概念和使用方法。下面将详细介绍这个入门案例中的关键知识点。 首先,Netty 的核心是其 ChannelHandler...

    netty 入门Reactor示例

    在学习"Netty入门Reactor示例"时,你可以按照以下步骤进行: 1. **创建服务器端:** - 首先,你需要创建一个ServerBootstrap实例,配置BossGroup和WorkerGroup。 - 然后,添加自定义的...

    netty入门例子--(不是翻译官方文档)

    这个“netty入门例子”旨在帮助初学者理解Netty的基本用法和特性,而不是简单地翻译官方文档,它提供了几个开发模板,以便于深入理解Netty中的消息异步通信机制和TCP通信的封装。 首先,Netty的核心是它的异步模型...

    netty入门与实战-netty-learn.zip

    这个“netty入门与实战-netty-learn.zip”文件包含了学习 Netty 的资源,帮助初学者理解并掌握这个强大的网络库。Netty-learn-master 可能是一个包含源代码、教程文档或者示例项目的目录。 Netty 的核心概念: 1. ...

    掘金-Netty 入门与实战-netty-demo.zip

    这个压缩包“掘金-Netty 入门与实战-netty-demo.zip”包含了关于 Netty 的入门教程和实战示例,特别是通过 "netty-demo-pipeline-channelHandler" 这个文件名我们可以推测,它可能包含了一个展示 Netty ...

    Netty网络编程视频教程

    近百节视频详细讲解,需要的小伙伴自行百度网盘下载,... Netty 入门 1. 概述 2. Hello World 3. 组件 4. 双向通信 三. Netty 进阶 1. 粘包与半包 2. 协议设计与解析 3. 聊天室案例 四. 优化与源码 1. 优化 2. 源码分析

Global site tag (gtag.js) - Google Analytics