ChannelHandler
Netty使用ChannelHandler来进行数据处理,且可以连接每个ChannelHandler。ChannelPipeline和ChannelHandler机制类似于Servlet和Filter过滤器链,将Channel的数据管道抽象为ChannelPipeline,消息在ChannelPipeline中流动和传递,交给ChannelHandler进行处理。
ChannelPipeline
ChannelPipeline持有ChannelHandler实例的链表,提供了一种高级的截取过滤器模式,可以通过新增和删除来实现不同的业务逻辑定制,而不需要对已有的ChannelHandler进行修改。让用户可以在ChannelPipeline中完全控制一个事件及如何处理ChannelHandler与ChannelPipeline的交互。
1 2 3 4 5 6 7 8 9 10
| final AbstractChannelHandlerContext head; final AbstractChannelHandlerContext tail;
private void addLast0(AbstractChannelHandlerContext newCtx) { AbstractChannelHandlerContext prev = tail.prev; newCtx.prev = prev; newCtx.next = tail; prev.next = newCtx; tail.prev = newCtx; }
|
在进行read操作时,调用顺序为head->tail;在进行write操作时,调用顺序为tail->head
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| * I/O Request * via {@link Channel} or * {@link ChannelHandlerContext} * | * +---------------------------------------------------+---------------+ * | ChannelPipeline | | * | \|/ | * | +---------------------+ +-----------+----------+ | * | | Inbound Handler N | | Outbound Handler 1 | | * | +----------+----------+ +-----------+----------+ | * | /|\ | | * | | \|/ | * | +----------+----------+ +-----------+----------+ | * | | Inbound Handler N-1 | | Outbound Handler 2 | | * | +----------+----------+ +-----------+----------+ | * | /|\ . | * | . . | * | ChannelHandlerContext.fireIN_EVT() ChannelHandlerContext.OUT_EVT()| * | [ method call] [method call] | * | . . | * | . \|/ | * | +----------+----------+ +-----------+----------+ | * | | Inbound Handler 2 | | Outbound Handler M-1 | | * | +----------+----------+ +-----------+----------+ | * | /|\ | | * | | \|/ | * | +----------+----------+ +-----------+----------+ | * | | Inbound Handler 1 | | Outbound Handler M | | * | +----------+----------+ +-----------+----------+ | * | /|\ | | * +---------------+-----------------------------------+---------------+ * | \|/ * +---------------+-----------------------------------+---------------+ * | | | | * | [ Socket.read() ] [ Socket.write() ] | * | | * | Netty Internal I/O Threads (Transport Implementation) | * +-------------------------------------------------------------------+
|
Netty中的事件分为Inbound事件和Outbound事件。Inbound事件通常由IO线程触发,如TCP链路建立事件、链路关闭事件、读事件等,触发Inbound的方法有ChannelHandlerContext中的(继承自ChannelInboundInvoker接口的方法)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| ChannelHandlerContext fireChannelRegistered();
ChannelHandlerContext fireChannelUnregistered();
ChannelHandlerContext fireChannelActive();
ChannelHandlerContext fireChannelInactive();
ChannelHandlerContext fireExceptionCaught(Throwable cause);
ChannelHandlerContext fireUserEventTriggered(Object event);
ChannelHandlerContext fireChannelRead(Object msg);
ChannelHandlerContext fireChannelReadComplete();
ChannelHandlerContext fireChannelWritabilityChanged();
|
Outbound事件通常是由用户主动发起的网络IO操作,如用户发起的连接操作、绑定操作、消息发送等,触发Outbound事件的方法有ChannelHandlerContext中的(继承自ChannelInboundInvoker接口的方法)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| ChannelFuture bind(SocketAddress localAddress);
ChannelFuture connect(SocketAddress remoteAddress);
ChannelFuture disconnect();
ChannelFuture close();
ChannelHandlerContext read();
ChannelFuture write(Object msg);
ChannelHandlerContext flush();
|
ChannelHandlerContext
每个ChannelHandler被添加到ChannelPipeline后,都会创建一个ChannelHandlerContext并与之创建的ChannelHandler关联绑定