Netty源码分析--Channel注册&绑定端口(下)(七)
接下来,我们看到的就是两个非常重要的方法

就是 processSelectedKeys() 和 runAllTasks() 方法了。
selectionKey中ready的事件,如accept、connect、read、write等,由processSelectedKeys方法触发。属于I/O任务。
添加到taskQueue中的任务,如register0、bind0等任务,由runAllTasks方法触发。属于非I/O任务。
两种任务的执行时间比由变量ioRatio控制,默认为50,则表示允许非IO任务执行的时间与IO任务的执行时间相等。
我们看一下 processSelectedKeys() 方法, 因为 selectedKeys != null 所以进入 processSelectedKeysOptimized() 方法。
由于没有这里只是启动服务端,没有客户端接入进来,所以我们先跳过processSelectedKeys(),一会我们结合客户端接入来讲这里。
直接看 runAllTasks() 方法。

Runnable task = pollTask(); 这个就是从 taskQueue 中拿出一个task。
然后循环执行这个任务, safeExecute(task)。

这个方法也是很简单,就是直接执行Runnable接口中的run()方法(这里并不是启动一个线程,而是仅仅的执行一个普通的run方法)。
大家想一下这里的这个task应该是什么呢?

大家还记得这段代码吗? 就是这个 register0() 方法。

我们先进入到 doRegister() 方法

继续传入当前的eventloop中的selector, opt = 0, 第三个参数 this 就是当前的 NioServerSocketChannel。 进入register 方法

大家看我圈出来的这一句,熟悉吗?我当时将NIO的时候是不是讲到了。
这里就是把当前的channel注册到这个多路复用器上。并且把 NioServerSocketChannel 传进去当做附件 attach, 注册的 interestOps = 0
好了,当执行完task,由于是一个死循环,那么会继续执行刚刚的整个过程。

好了,总结一下: 也就是说有一个线程一直在这里不断循环的等待新的 selectionKey中ready的事件,如accept、connect、read、write等。 如果有待处理的task,将会去优先处理的task.
一会我们会启动一个客户端看一下是怎么交互的。
整个注册完成之后,接下来就是 绑定端口 ,将服务对外开放出去。
我们看下AbstractBootstrap中的 doBind() 方法。

由于整个注册过程是异步的,所以这里 regFuture.isDone() 是否已经完成,如果完成直接执行doBind0(),如果没有完成,那么就监听异步响应方法,等待成功之后,再执行doBind0()方法。
我们进入doBind0()方法

我们看其实就是向eventLoop中的任务队列中添加一个task。
这里我们debug来看一下
另外在 AbstractBootstrap中打一个断点,在这里等待注册事件先完成。

好的,我们启动服务端。

断点进来了, 我们再在 NioEventLoop 中打一个断点,因为这里是处理task的地方

我们发现有一个主线程,一个子线程,如下图

切换到子线程,我们看下 task 的执行过程。

因为switch中的hasTask() 是true,那么我们就直接看


从任务队列中取出一个task,我们看到就是刚刚我们的那个任务。然后通过safeExecute(task)执行run方法

继续F5。我们看进入到了runnable中的run方法。

接下来就是一段链式调用,链式访问pipleline中的handler TailContext -> ServerBootstrapAcceptor -> LoggingHandler -> HeadContext

TailContext 和 ServerBootstrapAcceptor 中没有bind方法,直接进入LoggingHandler的bind方法,打一个日志

继续f5进入到 HeadContext中的bind方法


先判断是否激活,如果没有,则稍后链式调用handlers中的 channelActive()方法。
进入doBind方法

ok,到这里绑定端口成功。
目前为止,Server服务端启动完成,接下来我们看一下,一个客户端是怎么接入进来并且进行读写操作的。
Netty源码分析--Channel注册&绑定端口(下)(七)的更多相关文章
- Netty源码分析--Channel注册(上)(五)
其实在将这一节之前,我们来分析一个东西,方便下面的工作好开展. 打开启动类,最开始的时候创建了一个NioEventLoopGroup 事件循环组,我们来跟一下这个. 这里bossGroup, 我传入了 ...
- Netty源码分析--Channel注册(中)(六)
接上一篇,我们继续看 不知道大家第一次看这段代码的时候有没有一脸懵逼,反正我是一脸懵,为什么这个if else 最终都是调用的register0方法,都是一样的. 其实这里就是为什么Netty是线程安 ...
- Netty源码分析-- 处理客户端接入请求(八)
这一节我们来一起看下,一个客户端接入进来是什么情况.首先我们根据之前的分析,先启动服务端,然后打一个断点. 这个断点打在哪里呢?就是NioEventLoop上的select方法上. 然后我们启动一个客 ...
- Netty源码分析第4章(pipeline)---->第7节: 前章节内容回顾
Netty源码分析第四章: pipeline 第七节: 前章节内容回顾 我们在第一章和第三章中, 遗留了很多有关事件传输的相关逻辑, 这里带大家一一回顾 首先看两个问题: 1.在客户端接入的时候, N ...
- Netty源码分析第1章(Netty启动流程)---->第5节: 绑定端口
Netty源码分析第一章:Netty启动步骤 第五节:绑定端口 上一小节我们学习了channel注册在selector的步骤, 仅仅做了注册但并没有监听事件, 事件是如何监听的呢? 我们继续跟第一小节 ...
- Netty源码分析第1章(Netty启动流程)---->第4节: 注册多路复用
Netty源码分析第一章:Netty启动流程 第四节:注册多路复用 回顾下以上的小节, 我们知道了channel的的创建和初始化过程, 那么channel是如何注册到selector中的呢?我们继 ...
- Netty源码分析第1章(Netty启动流程)---->第3节: 服务端channel初始化
Netty源码分析第一章:Netty启动流程 第三节:服务端channel初始化 回顾上一小节的initAndRegister()方法: final ChannelFuture initAndRe ...
- Netty源码分析第3章(客户端接入流程)---->第4节: NioSocketChannel注册到selector
Netty源码分析第三章: 客户端接入流程 第四节: NioSocketChannel注册到selector 我们回到最初的NioMessageUnsafe的read()方法: public void ...
- Netty源码分析(前言, 概述及目录)
Netty源码分析(完整版) 前言 前段时间公司准备改造redis的客户端, 原生的客户端是阻塞式链接, 并且链接池初始化的链接数并不高, 高并发场景会有获取不到连接的尴尬, 所以考虑了用netty长 ...
随机推荐
- uow Unit of work
通过学习圣杰的文章 UnitOfWork知多少 知道uow其实就是为了解决 一次提交所有更改 1.ef本身可以具备这样一个功能,但是我们在写仓储的实现的时候 经常会直接显式saveChanges了 ...
- 使用WPF技术模拟手机界面
原文:使用WPF技术模拟手机界面 1. 前言 WPF(Windows Presentation Foundation),即"Windows呈现基础",它的目的非常明确,就是用来把数 ...
- windows IIS发布.net core网站的环境配置
1.安装对应的.net core的runtime2.安装Windows Server Hosting下载地址:https://www.microsoft.com/net/download/core#/ ...
- 备份一个支持虚拟化的wrappanel
public class VirtualizingWrapPanel : VirtualizingPanel, IScrollInfo { #region Fields UIElementCollec ...
- dataGrid 源更新 事件
DataGrid myGrid = new DataGrid(); CollectionView myCollectionView = (CollectionView)CollectionViewSo ...
- CSS计数器:counter
最近的需求,明星字体销售排行榜中,需要对字体的销售情况进行排序. 在早期,只有ol和ul可以对子元素li进行排序:如果不使用这两个标签,就由前台开发去手动填写序号. 当然,在这个需求中,数据不是实时更 ...
- javascript的强制类型转换
1.toString (1)调用toString方法 Array是将数组中的每个元素字符串化,并使用逗号拼接起来 object返回的是内部属性[[Class]]的值,[object Object] n ...
- [Erlang-0016][aque_tcp] 一个 Erlang TCP 组件
项目地址:https://github.com/liangjingyang/aque_tcp 欢迎任何形式的转载,但请务必注明出处:http://www.cnblogs.com/liangjingya ...
- 深入浅出RPC——浅出篇(转载)
本文转载自这里是原文 近几年的项目中,服务化和微服务化渐渐成为中大型分布式系统架构的主流方式,而 RPC 在其中扮演着关键的作用. 在平时的日常开发中我们都在隐式或显式的使用 RPC,一些刚入行的程序 ...
- WCF学习--我的第一个WCF例子
Windows Communication Foundation(WCF)是由微软发展的一组数据通信的应用程序开发接口,可以翻译为Windows通讯接口. 通信双方的沟通方式,由合约来订定.通信双方所 ...