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