接下来,我们看到的就是两个非常重要的方法

就是 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注册&绑定端口(下)(七)的更多相关文章

  1. Netty源码分析--Channel注册(上)(五)

    其实在将这一节之前,我们来分析一个东西,方便下面的工作好开展. 打开启动类,最开始的时候创建了一个NioEventLoopGroup 事件循环组,我们来跟一下这个. 这里bossGroup, 我传入了 ...

  2. Netty源码分析--Channel注册(中)(六)

    接上一篇,我们继续看 不知道大家第一次看这段代码的时候有没有一脸懵逼,反正我是一脸懵,为什么这个if else 最终都是调用的register0方法,都是一样的. 其实这里就是为什么Netty是线程安 ...

  3. Netty源码分析-- 处理客户端接入请求(八)

    这一节我们来一起看下,一个客户端接入进来是什么情况.首先我们根据之前的分析,先启动服务端,然后打一个断点. 这个断点打在哪里呢?就是NioEventLoop上的select方法上. 然后我们启动一个客 ...

  4. Netty源码分析第4章(pipeline)---->第7节: 前章节内容回顾

    Netty源码分析第四章: pipeline 第七节: 前章节内容回顾 我们在第一章和第三章中, 遗留了很多有关事件传输的相关逻辑, 这里带大家一一回顾 首先看两个问题: 1.在客户端接入的时候, N ...

  5. Netty源码分析第1章(Netty启动流程)---->第5节: 绑定端口

    Netty源码分析第一章:Netty启动步骤 第五节:绑定端口 上一小节我们学习了channel注册在selector的步骤, 仅仅做了注册但并没有监听事件, 事件是如何监听的呢? 我们继续跟第一小节 ...

  6. Netty源码分析第1章(Netty启动流程)---->第4节: 注册多路复用

    Netty源码分析第一章:Netty启动流程   第四节:注册多路复用 回顾下以上的小节, 我们知道了channel的的创建和初始化过程, 那么channel是如何注册到selector中的呢?我们继 ...

  7. Netty源码分析第1章(Netty启动流程)---->第3节: 服务端channel初始化

    Netty源码分析第一章:Netty启动流程   第三节:服务端channel初始化 回顾上一小节的initAndRegister()方法: final ChannelFuture initAndRe ...

  8. Netty源码分析第3章(客户端接入流程)---->第4节: NioSocketChannel注册到selector

    Netty源码分析第三章: 客户端接入流程 第四节: NioSocketChannel注册到selector 我们回到最初的NioMessageUnsafe的read()方法: public void ...

  9. Netty源码分析(前言, 概述及目录)

    Netty源码分析(完整版) 前言 前段时间公司准备改造redis的客户端, 原生的客户端是阻塞式链接, 并且链接池初始化的链接数并不高, 高并发场景会有获取不到连接的尴尬, 所以考虑了用netty长 ...

随机推荐

  1. Leetcode 136 Single Number 亦或

    题意就是从一堆数中找出唯一的一个只存在一个的数.除了那个数,其他的数都是两个相同的数. 通过亦或的性质: 1)a^a = 0 0^a = a 2)交换律 a^b = b^ a 3)结合律 (a^b)^ ...

  2. 利用tcpdump分析工具来验证tcp连接的建立和关闭过程

    本文要求读者在阅读之前应该对TCP通过三次握手建立和关闭连接有一定的了解,本文并没有详细讲解三次握手,只是通过一个实例对三次握手进行了一下验证. tcp连接的建立和关闭想必大家都已经非常熟悉了!通过三 ...

  3. 重构qDebug()<<,使log输出到文件

    重构qDebug()<<,使log输出到文件 #include <QProcessEnvironment> #include <QDateTime> #includ ...

  4. WPF实现左右移动(晃动)动画效果

    原文:WPF实现左右移动(晃动)动画效果 实现控件或布局的左右移动(晃动)主要用到DoubleAnimation以及Storyboard 布局代码为: <Canvas> <Grid ...

  5. Beginner’s Tutorial: 3D Line and Border Effects in XAML

    This mini-tutorial might be for you if you’re having troubles finding the right line colors to achie ...

  6. CORSFilter

    import java.io.IOException; import javax.servlet.Filter;import javax.servlet.FilterChain;import java ...

  7. springboot 集成oauth2

    未实现.首先实现spring security. 1. 关于oauth2 隐隐觉得集成oauth2,用好它是一个不太简单的事儿,需要对oauth2了解一番. oauth2比较好的参考,都是别人原创文章 ...

  8. MVC 调试路由

    1.添加引用RouteDebug.dll 2 修改Global.asax,切记调试过后要删掉 using System;using System.Collections.Generic;using S ...

  9. ajax 异步长连接遭遇堵塞,“排序执行请求”的问题解决

    今天开发一个网页聊天程序,利用AJAX保持着一个长连接监听新的聊天信息,之后又调用了另外一个AJAX来发言,于是就发生了一个AJAX线程被阻塞的问题. 在未监听到新的聊天信息的之前,发言用的AJAX就 ...

  10. wcf服务端代码方式及客户端代码方式

    ServiceHost  host;  // 全局 host = new ServiceHost(typeof(实现服务接口的类)); host.open(); 用代码配置端点的方法 host.add ...