Netty的常用组件及线程模型设计(二)
Channel、EventLoopGroup和ChannelFuture
Netty网络抽象的代表:
Channel–Socket
EventLoop–控制流、多线程处理、并发
ChannelFuture–异步通知
Channel和EventLoop关系如图:
我们可以看出Channel需要被注册到某个EventLoop上,在Channel整个声明周期内部都由这个EventLoop处理IO事件,也就是说一个Channel和一个EventLoop进行了绑定,但是一个EventLoop可以同时被多个Channel绑定。
Channel接口。
基本的IO操作(bind()、connect()、read()和write())依赖于底层网络传输所提供的原语。在基于Java的网络编程中,其基本的构造是类Socket.Netty的Channel接口所提供的API,被用于所有的IO操作。大大地降低了直接使用Socket类地复杂性。此外,Channel也是许多预定义、专门化实现地广泛类层次结构的根
由于Channel是独一无二的,所以为了保证顺序将Channel声明为java.lang.Comparable的一个子接口。因此,如果两个不同的Channel示例都返回了相同的散列码,那么AbstractChannel中的compareTo()方法的实现将会抛出一个Error
Channel的生命周期状态
ChannelUnregistered:Channel已经被创建,但是还未注册到EventLoop
ChannelRegistered:Channel已经被注册到了EventLoop
ChannelActiveLChannel处于活动状态(已经连接到它的远程节点)。它现在可以接收和发送数据了,ChannelInactive:Channel没有连接到远程节点
当这些状态发生改变时,将会生成对应的事件。这些事件将会被转发给ChannelPipeline中的,ChannelHandler,其可以随后对它们做出响应。在日常编程中,关注ChannelActive和ChannelInactive会更多一些
重要的Channel的方法。
eventLoop:返回分配给Channel的EventLoop
pipeline:返回Channel的ChannelPipeline,也就是说每个Channel都有自己的ChannelPipeline.
isActive:如果Channel是活动的,则返回true。活动的意义可能依赖于底层的传输。
例如,一个Socket传输一旦连接到了远程节点便是活动的,而一个Datagram传输一旦被打开便是活动的。
localAddress:返回本地的SocketAdress
remoteAddress:返回远程的SocketAddress
write:将数据写到远程节点,注意,这个写只是写往Netty内部的缓存,还没有真正写往Socket
flush:将之前写的数据冲刷到底层Socket进行传输
writeAndFlush:一个简便的方法,等同于调用write()并接着调用flush()