Netty实战四之传输
Posted Java猫说
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Netty实战四之传输相关的知识,希望对你有一定的参考价值。
流经网络的数据总是具有相同的类型:字节(网络传输——一个帮助我们抽象底层数据传输机制的概念)
Netty为它所有的传输实现提供了一个通用的API,即我们可以将时间花在其他更有成效的事情上。
我们将通过一个案例来对传输进行学习,应用程序只简单地接收连接,向客户端写 “Hi!” ,然后关闭连接。
1、不通过Netty使用OIO和NIO
先介绍JDK API的应用程序的阻塞(OIO)版本和异步(NIO)版本。
这段代码完全可以处理中等数量的并发客户端,但是随着应用程序变得流行起来,你会发现它并不能很好地伸缩到支撑成千上万的并发连入连接。你决定改用异步网络编程,但是很快就发现异步API是完全不同的,以至于现在你不得不重写你的应用程序。
虽然这段代码所做的事情与之前的版本完全相同,但是代码却截然不同,如果为了用于非阻塞I/O而重新实现这个简单的应用程序,都需要一次完全重写的话,那么不难想象,移植真正复杂的应用程序需要付出什么样的努力!
2、通过Netty使用OIO和NIO
3、非阻塞的Netty版本
因为Netty为每种传输的实现都暴露了相同的API,所以无论选用哪一种传输的实现,你的代码都仍然几乎不受影响,在所有的情况下,传输的实现都依赖于interface Channel、ChannelPipeline和ChannelHandler。
4、传输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展示了一个多线程写数据的简单例子,需要注意的是,消息将会被保证按顺序发送的。
以上是关于Netty实战四之传输的主要内容,如果未能解决你的问题,请参考以下文章