- Channel——Socket
- EventLoop——控制流、多线程处理、并发
- ChannleFuture——异步通知
这三个类结合起来可以被认为是netty网络抽象的代表。
Channle接口
基本的IO操作依赖于底层网络传输所提供的原语,对应java网络编程的Socket。Netty接口所提供的api,大大降低了直接使用Socket的复杂性,此外,Channel还拥有许多预定义的、专门实现的广泛类层次结构的根。例如:
NioSocketChannel、NioDatagramChannel等。
EventLoop
EventLoop由EventLoopGroup提供,用于处理IO事件。
创建Channel时会将其注册到相应的EventLoop,之后Channel的整个生命周期内都在该EventLoop处理IO事件,让开发者可以专注于逻辑的实现,不需要考虑同步的顾虑。
这里再说一下EventLoopGroup、EventLoop和Channel的关系:
- 一个EventLoopGroup包含一个或多个EventLoop
- 一个EventLoop在他的生命周期只和一个线程绑定
- 所有由EventLoop处理的IO事件都将在这个线程上被处理
- 一个Channle在他的生命周期内只注册于一个EventLoop
- 一个EventLoop可以会被分配给一个或者多个的Chhanel
因此,一个给定的Chhanl的所有IO操作都将在一个线程上执行,消除了对于同步的需要。
ChannelFuture
因为netty的所有IO操作都是异步的,因此一个操作可能不会立即返回,所以我们需要一种在之后某个时间点确定其结果的方法。因此netty提供了ChannelFuture接口,其addListener()方法注册了一个ChannelFutureListener以便接收回调通知。
ChannelHandler
ChannelHandler用于处理出站和入站逻辑,ChannelInboundHandler和ChannelOutboundHandler都继承了ChannelHandler接口。我们通常实现
ChannelInboundHandler接口用于处理入站事件,实现ChannelOutboundHandler用于处理出站事件。
ChannelPipeline
ChannelPipeline为ChannelHandler链提供了容器,并定义了用于在该链上传播入站和出战事件流的api。当Channel被创建时,他将被自动的分配到他专属的ChannelPipeline。
所谓入站,即事件的运动方向是客户端到服务器端
所谓出战,即事件的运动方向是服务器端到客户端
使得事件流经ChannelPipeline是ChannelHandler的工作,他们是在应用程序的初始化或引导阶段被安装的。这些对象接收事件、执行他们所实现的处理逻辑,并将事件传递给链中的下一个ChannelHandler。他们的执行顺序是由他们被添加的顺序所决定的。
出站和入站事件(ChannelHandler)是可以被安装到同一个ChannelPipeline的。如果一个消息或任何其他的入站事件被读取,那么他会从ChannelPipeline的头部开始流动,并被传递给第一个ChannelInboundHandler,之后会被传递给下一个ChannelInboundHandler,直到ChannelPipeline的尾端,这时所有的处理结束。数据的出站运动在概念上也是一样的,只不过是从ChannelOutboundHandler的尾端开始流动,直到链的头部才结束,在这之后数据会到达网络传输层。