1、Channel介绍
- Channel是通讯的载体,ChannelHandler负责Channel中的逻辑处理;
- ChannelPipeline是ChannelHandler的容器,一个Channel包含一个ChannelPipeline,所有ChannelHandler都会注册到ChannelPipeline中,并按顺序组织起来;
- Netty中,ChannelEvent是数据或者状态的载体,传输数据对应MessageEvent,改变状态对应ChannelStateEvent,当对Channel操作时,会产生ChannelEvent并发送到ChannelPipeline;
- ChannelPipeline选择一个ChannelHandler进行处理,这个ChannelHandler处理之后,可能产生新的ChannelEvent并流转到下一个ChannelHandler;
2、ChannelPipeline
当boss线程监控到绑定端口上有accept事件,会为socket连接实例化pipeline,并将InboundHandler和OutboundHandler按序加载到pipeline中,然后将该socket连接挂载到selector上。
一个selector对应一个线程,会轮询所有挂载在他身上的socket连接有没有read/write事件,然后通过线程池去执行pipeline业务流。
ChannelHandlerContext对象里封装了ChannelHandler对象,通过prev和next节点实现双向链表。Pipeline的首尾节点分别是head和tail,当selector轮询到socket有read事件时,将会触发Pipeline责任链,从head开始调起第一个InboundHandler的ChannelRead事件,接着通过fire方法依次触发Pipeline上的下一个ChannelHandler
1、InboundHandler是通过fire事件决定是否要执行下一个InboundHandler,如果哪个InboundHandler没有调用fire事件,那么往后的Pipeline就断掉了。
2、InboundHandler是按照Pipleline的加载顺序,顺序执行。
3、OutboundHandler是按照Pipeline的加载顺序,逆序执行。
4、有效的InboundHandler是指通过fire事件能触达到的最后一个InboundHander。
5、如果想让所有的OutboundHandler都能被执行到,那么必须把OutboundHandler放在最后一个有效的InboundHandler之前。
6、推荐的做法是通过addFirst加载所有OutboundHandler,再通过addLast加载所有InboundHandler。
7、OutboundHandler是通过write方法实现Pipeline的串联的。
8、如果OutboundHandler在Pipeline的处理链上,其中一个OutboundHandler没有调用write方法,最终消息将不会发送出去。
9、ctx.writeAndFlush是从当前ChannelHandler开始,逆序向前执行OutboundHandler。
10、ctx.writeAndFlush所在ChannelHandler后面的OutboundHandler将不会被执行。
11、ctx.channel().writeAndFlush 是从最后一个OutboundHandler开始,依次逆序向前执行其他OutboundHandler,即使最后一个ChannelHandler是OutboundHandler,在InboundHandler之前,也会执行该OutbondHandler。
12、千万不要在OutboundHandler的write方法里执行ctx.channel().writeAndFlush,否则就死循环了。
3、异步模型
- 当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的组件在调用后,通过状态、通知和回调来通知调用者。
- Netty中的IO操作是异步的,包括Bind、Write、Connect等操作会简单地返回一个ChannelFuture.
- 调用者不能立刻获得结果,而是通过Future-Listener机制,用户可以方便的主动获取或者通过通知机制获得IO操作结果;
- Netty的异步模型是建立在future和callback之上的:假设一个方法fun,计算过程非常耗时,可以在调用fun的时候,立马返回一个Future,后续可以通过Future去监控fun的处理过程,即Future-Listener机制;
当 Future 对象刚刚创建时,处于非完成状态,调用者可以通过返回的 ChannelFuture 来获取操作执行的状态,注册监听函数来执行完成后的操作。
常见有如下操作
- 通过 isDone 方法来判断当前操作是否完成;
- 通过 isSuccess 方法来判断已完成的当前操作是否成功;
- 通过 getCause 方法来获取已完成的当前操作失败的原因;
- 通过 isCancelled 方法来判断已完成的当前操作是否被取消;
- 通过 addListener 方法来注册监听器,当操作已完成(isDone 方法返回完成),将会通知指定的监听器;如果 Future 对象已完成,则通知指定的监听器