【Netty源码分析】02 Netty Server 启动流程 下
上面我们分析了initAndRegister()
方法的核心流程,Channel
准备工作基本也都完成了:
Channel
和NioEventLoop
进行了关联;Channel
也注册到Selector
上了;NioEventLoop
线程也启动完成,开始轮询事件、处理事件。这里还遗漏了两个事情:channel
和端口绑定以及channel
向Selector
注册OP_ACCEPT
。这就是在doBind()
方法中另一个重要的方法:doBind0()
中进行完成的。
(资料图片)
doBind0
if (regFuture.isDone()) { ChannelPromise promise = channel.newPromise(); doBind0(regFuture, channel, localAddress, promise); return promise;} else { final PendingRegistrationPromise promise = new PendingRegistrationPromise(channel); //register还未完成,则添加listener,待注册完成再执行doBind0()进行server端口绑定 regFuture.addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { Throwable cause = future.cause(); if (cause != null) { promise.setFailure(cause); } else { promise.registered(); doBind0(regFuture, channel, localAddress, promise); } } }); return promise;}
上面代码一大堆,核心就是调用doBind0()
方法,但是执行该方法前必须保证上一步initAndRegister()
方法中执行完成。通过regFuture.isDone()
进行判断,具体设置位置见下:
//AbstractChannel.AbstractUnsafe#register0pipeline.invokeHandlerAddedIfNeeded();// 将指定的promise标记为成功:regFuture.isDone()=true,doBind0()才能开始执行safeSetSuccess(promise);pipeline.fireChannelRegistered();
进行向下跟踪,来到了如下代码处,会发现需要调用channel.bind()
方法,但是不是在当前线程中直接调用,而是封装成task
放入到NioEventLoop
的任务队列taskQueue
中,由NioEventLoop
线程执行:
private static void doBind0( final ChannelFuture regFuture, final Channel channel, final SocketAddress localAddress, final ChannelPromise promise) { channel.eventLoop().execute(new Runnable() { @Override public void run() { if (regFuture.isSuccess()) { channel.bind(localAddress, promise).addListener(ChannelFutureListener.CLOSE_ON_FAILURE); } else { promise.setFailure(regFuture.cause()); } } });}
这时的NioEventLoop
线程是已经启动并开始工作的,所以channel.bind()
这里是可以执行的。
层层调用最终是在pipeline
中的head
这个节点进行处理的:
public final void bind(final SocketAddress localAddress, final ChannelPromise promise) { assertEventLoop(); if (!promise.setUncancellable() || !ensureOpen(promise)) { return; } //还没有绑定端口,isActive()返回false boolean wasActive = isActive(); try { //调用底层java api,将channel绑定到具体端口上 doBind(localAddress); } catch (Throwable t) { safeSetFailure(promise, t); closeIfClosed(); return; } //经过上面绑定端口,这时isActive()=true if (!wasActive && isActive()) { invokeLater(new Runnable() { @Override public void run() { //触发server handler的channelActive()方法 pipeline.fireChannelActive(); } }); } safeSetSuccess(promise);}
这个方法主要完成2件事:
doBind()
:调用java api
,将channel
绑定到具体端口上;pipeline.fireChannelActive()
:将pipeline.fireChannelActive()
放入到NioEventLoop
线程中执行;下面我们再来看下pipeline.fireChannelActive()
:
public void channelActive(ChannelHandlerContext ctx) { ctx.fireChannelActive(); readIfIsAutoRead();}
该方法主要做2件事:
ctx.fireChannelActive()
:触发handler#channelActive()
调用,表示当前channel
已处于激活状态,可以正常工作了;readIfIsAutoRead()
:从名称看就是,如果配置autoRead
,调用readIfIsAutoRead()
直接进行read
操作;readIfIsAutoRead()
会调用tail.read()
,然后一层层往前查找,最终调用的是head#read()
方法。protected void doBeginRead() throws Exception { final SelectionKey selectionKey = this.selectionKey; if (!selectionKey.isValid()) { return; } readPending = true; final int interestOps = selectionKey.interestOps(); // 将SelectionKey当前的操作位与注册操作位进行按位与操作,如果等于0,说明目前并没有设置注册操作位 if ((interestOps & readInterestOp) == 0) { // Server Channel会在这里注册真正的ACCEPT事件 selectionKey.interestOps(interestOps | readInterestOp); }}
channel
绑定好端口后,触发了channelActive()
方法回调,channel
真正进入可以正常工作状态,这时还差最后一步:注册OP_ACCEPT
事件。
总结
这样,Netty
整体启动就全部完成,NioServerSocketChannel
这时就可以正常接收到客户端连接请求。
关键词:
- 广州科技活动周进入预热 明日正式启动300多场主题活动接踵而来
- 深化重点领域信用建设 广州正式出台新型监管机制实施方案
- 女童不慎掉入20米深井 18岁小姨三次下井成功营救
- 西安3个区域12月28日起每日开展全员核酸 官方提倡民众居家健身
- 浙江乐清一核酸检测结果异常人员 复采复检为阴性
- 浙江本轮疫情报告确诊病例490例 提倡“双节”非必要不出省
- 西安警方通报6起涉疫违法案件
- 西安新一轮核酸筛查日检测能力达160万管
- 西安市累计报告本土确诊病例811例
- 重庆曝光4起违反中央八项规定精神典型问题 警示党员干部清新过节
-
国金证券:给予璞泰来买入评级 焦点热议
国金证券股份有限公司陈传红近期对璞泰来进行研究并发布了研究报告《业绩符合预期,各业务稳健增长》,本报告对璞泰来给出买入评级,当前股价
-
油气开采及服务板块持续走强,中油资本涨停
App3月28日消息,油气开采及服务板块持续走强,中油资本涨停,此前荣盛石化、华锦股份涨停,恒泰艾普涨超15%,恒力石化、宝莫股份、中国石化、
-
正当防卫情况下把对方打成轻伤怎么处理
一、正当防卫情况下把对方打成轻伤怎么处理正当防卫情况下把对方打成轻伤的处理:对于防卫过当的,应当减轻或者免除处罚。根据《
-
世界通讯!汽车导航一体机安装接线图解_导航仪一体机接线图
1、车载摄像头三根线分别是红的接倒车灯正极,黄的是视频输出,黑是负极。2、接下来确定你的导航上哪个脚是倒车控制线,这根线
-
【世界播资讯】谴责美对叙东部部分地区发动袭击
新华社大马士革3月26日电叙利亚外交部25日发表声明,谴责美军对叙东部部分地区发动的袭击,强调叙致力于结束美国占领。 声明表示,叙利亚谴
-
3月27日基金净值:大成北交所两年定开混合A最新净值0.8067,跌0.52%
3月27日,大成北交所两年定开混合A最新单位净值为0 8067元,累计净值为0 8067元,较前一交易日下跌0 52%。历史数据显示该基金近1个月下跌3 13%
-
樊天胜 焦点速读
1、樊天胜2、上海人。1947年毕业于青岛海校航海专业。历任招商局、上海海鹰轮船公司海鹰号驾驶室实习生、三副、二
-
媒体人:广州城准入遇困境目前等“拔管” 九牛搬至长沙不好推进_全球最资讯
直播吧3月27日讯媒体人苗原日前发文,谈到了中国职业俱乐部新赛季的准入问题,他表示广州城目前遭遇了困难。“今天没有,明天会有吗?广州城现
-
vivo手机叫什么名字可以唤醒(vivo手机怎么叫)
品牌型号:vivoY73s系统:FuntouchOS_10 5以vivoY73s为例,vivo手机叫小v可以唤醒。分为3步,具体步骤如下:1进入设置Jovi1
-
印度人偷电有多疯狂?270万人里250万人在偷,一年偷掉200亿度电-每日热讯
印度人偷电有多夸张?一年偷掉200亿度电,把偷电做成产业链,偷电工甚至被称为“侠盗罗宾汉”!印度人偷电有多专业?看看这位老哥你就知道了。
X 关闭
【Netty源码分析】02 Netty Server 启动流程 下
全球新动态:浙商银行:到2027年经济周期弱敏感资产将达营收占比的50%
江河集团:2022年净利4.89亿元,同比扭亏为盈
无花果怎么吃?
全球今日讯!三角镇人才购房优惠出炉,看这里→
X 关闭
焦点讯息:水发燃气董秘回复:根据《上海证券交易所股票上市规则》的规定
西安警方完成研考安保工作 共出动警力逾1.3万人次
得知西安疫情防控“升级” 男子夜骑共享单车回咸阳淳化
中国医生将任SIU主席背后:从追随者同行者到引领者
海南省通报政法队伍教育整顿成果