1.概念
ChannelHandler分ChannelUpstreamHandler和ChanneldownstreamHandler,前者指向服务器接收事件的调用处理器,后者是服务器由内而外发送事件的事件处理器。
上下行消息传递方法介绍
sendUpstream()方法表发由外向内传递事件,
public void sendUpstream(ChannelEvent e) { DefaultChannelHandlerContext head = getActualUpstreamContext(this.head); if (head == null) { if (logger.isWarnEnabled()) { logger.warn( "The pipeline contains no upstream handlers; discarding: " + e); } return; } sendUpstream(head, e); } void sendUpstream(DefaultChannelHandlerContext ctx, ChannelEvent e) { try { ((ChannelUpstreamHandler) ctx.getHandler()).handleUpstream(ctx, e); } catch (Throwable t) { notifyHandlerException(e, t); } }
从处理器链最远的Head开始调用handleUpstream()方法。
sendDownstream方法负责从最里面开始向外发送事件。
public void sendDownstream(ChannelEvent e) { DefaultChannelHandlerContext tail = getActualDownstreamContext(this.tail); if (tail == null) { try { getSink().eventSunk(this, e); return; } catch (Throwable t) { notifyHandlerException(e, t); return; } } sendDownstream(tail, e); } void sendDownstream(DefaultChannelHandlerContext ctx, ChannelEvent e) { if (e instanceof UpstreamMessageEvent) { throw new IllegalArgumentException("cannot send an upstream event to downstream"); } try { ((ChannelDownstreamHandler) ctx.getHandler()).handleDownstream(ctx, e); } catch (Throwable t) { e.getFuture().setFailure(t); notifyHandlerException(e, t); } }
sendDownstream依次从内向外沿着处理器链进行传递,直到最后传递给ChannelSink,这个类是处理接收处理终端的下行事件。
bind操作分析:
1.新建事件处理器SimpleChannelUpstreamHandler子类binder,负责在收到Open事件后发出bind请求。
2.新建ChannelPipeline类bossPipeline,并将binder和parentHandler(如果有,用户指定处理器)依次添加到bossPipeline末尾
3.利用NioServerSocketChannelFactory,以bossPipeline为参数创建Channel。在其中的构造函数中
3.1.ServerSocketChannel.open();打开socket
3.2.fireChannelOpen()中channel.getPipeline().sendUpstream发送上行消息OPEN状态事件,以此事件为起始引发后续bind操作。
4.OPEN事件传递到binder后会调用其channelOpen()方法,该方法设置了相关Option,继续传递OPEN事件到下一个处理器parentHandler。最后调用channel.bind()方法绑定localAddress。
5.该绑定方法会调用sendDownstream()方法向下行流传递BOUND状态事件。binder为上行流处理器,忽略,parentHandler如果是对应处理器则调用。最后由NioServerSocketPipelineSink.eventSunk响应最终的下行流事件。NioServerSocketPipelineSink会调用NioServerBoss的bind()
6.该bind()会生成RegisterTask到任务队列中。
7.RegisterTask的任务
7.1.channel.socket.socket().bind绑定address
7.2.fireChannelBound把BOUND事件沿上行流传递,binder对此不处理。
7.3.channel.socket.register()将socket的OP_ACCEPT事件注册到selector上。
以上事件传递如下图所示:
至此,已完成服务器socket的绑定,并开始监听。