流经网络的数据老是具备相同的类型:字节(网络传输——一个帮助咱们抽象底层数据传输机制的概念)java
Netty为它全部的传输实现提供了一个通用的API,即咱们能够将时间花在其余更有成效的事情上。编程
咱们将经过一个案例来对传输进行学习,应用程序只简单地接收链接,向客户端写 “Hi!” ,而后关闭链接。设计模式
一、不经过Netty使用OIO和NIO安全
先介绍JDK API的应用程序的阻塞(OIO)版本和异步(NIO)版本。网络
这段代码彻底能够处理中等数量的并发客户端,可是随着应用程序变得流行起来,你会发现它并不能很好地伸缩到支撑成千上万的并发连入链接。你决定改用异步网络编程,可是很快就发现异步API是彻底不一样的,以致于如今你不得不重写你的应用程序。多线程
虽然这段代码所作的事情与以前的版本彻底相同,可是代码却大相径庭,若是为了用于非阻塞I/O而从新实现这个简单的应用程序,都须要一次彻底重写的话,那么不难想象,移植真正复杂的应用程序须要付出什么样的努力!并发
二、经过Netty使用OIO和NIO异步
三、非阻塞的Netty版本ide
由于Netty为每种传输的实现都暴露了相同的API,因此不管选用哪种传输的实现,你的代码都仍然几乎不受影响,在全部的状况下,传输的实现都依赖于interface Channel、ChannelPipeline和ChannelHandler。oop
四、传输API
传输API的核心是interface Channel ,它被用于全部的I/O操做。Channel类的层次结构如图4-1(Channel接口的层次结构)所示。
如图所示,每一个Channel都将会将分配一个ChannelPipeline和ChannelConfig。ChannelConfig包含了该Channel的全部配置设置,而且支持热更新。
因为特定的传输可能具备独特的设置,因此它可能会实现一个ChannelConfig的子类型。
因为Channel是独一无二的,因此为了保证顺序将Channel声明为java.lang.Comparable的子接口。所以,若是两个不一样的Channel实例都返回相同的散列码,那么AbstractChannel中的compareTo()方法的实现将会抛出一个Error。
ChannelPiepeline持有全部将应用于入站和出站数据以及事件的ChannelHandler实例,这些ChannelHandler实现了应用程序用于处理状态变化以及数据处理的逻辑。
ChannelHandler的典型用途包括:
-将数据从一种格式转换为另外一种格式
-提供异常的通知
-提供Channel变为活动的或者非活动的通知
-提供当Channel注册到EventLoop或者从EventLoop注销时的通知
-提供有关用户自定义事件的通知
拦截过滤器 ChannelPipeline实现了一种常见的设计模式——拦截过滤器(InterceptingFilter)。UNIX管道是另一个熟悉的例子:多个命令被连接在一块儿,其中一个命令的输出端将链接到命令行中下一个命令的输入端。
你也能够根据须要经过添加或者移除ChannelHandler实例来修改ChannelPipeline。经过利用Netty的这项能力能够构建出高度灵活的应用程序。例如,每当STARTTLS协议被请求时,你能够简单地经过向ChannelPipeline添加一个适当的ChannelHandler(SslHandler)来按需地支持STARTTLS协议。
考虑一下写数据并将其冲刷到远程节点这样的常规任务,代码清单4-5演示了使用Channel.writeAndFlush()来实现这一目的。
Netty的Channel实现是线程安全的,所以你能够存储一个到Channel的引用,而且每当你须要向远程节点写数据时,均可以使用它,即便当时许多线程都在使用它。代码清单4-6展现了一个多线程写数据的简单例子,须要注意的是,消息将会被保证按顺序发送的。