Netty源码分析之Server bindAsync

下文将剖析ServerBootstrap.bindAsync()方法所涉及到的流程。
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上。

以上事件传递如下图所示:

[img]http://dl2.iteye.com/upload/attachment/0084/6330/d59b6496-f5d8-3c26-9674-a72250edf556.jpg[/img]


至此,已完成服务器socket的绑定,并开始监听。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值