Netty之Channel、NioEventLoopGroup、客户端connect方法总结
一、bind方法
详情请见以前的文章:Netty之Channel、NioEventLoopGroup、客户端connect方法总结
bind方法会调用initAndRegister方法
1.1 initAndRegister方法
1.1.1 生成channel的构造方法
- channel.newChannel()。通过反射生成了我们显式设置的NioSocketChannel.class对象,反射是用它的无参构造方法生成的。
- 无参构造方法级联调用了多个构造参数。在这个过程中,通过jdk自带的spi机制生成了原生nio的socketChannel对象,这个参数最终会在AbstractChannel的构造方法中设置到ch属性中,并且ch会设置成不阻塞
- 生成id,unsafe,pipeline等属性并赋值
1.1.2 init方法
- 将显示设置的handler配置到pipeline中
- 将显示配置的option设置到channel的pipeline中
- 将显示配置attr配置到channel中
1.1.3 register方法
这个方法在MultithreadEventLoopGroup类中。
- 选择一个EventLoop,调用其register方法
- 最终调用jdk原生nio的Channel.register(selector)
问题:服务端selector是在哪里生成的?
1.1.4 注册触发事件
- 调用ChannelInitializer.channelRegister()
- 内部调用了钩子方法initChannel(),这个就是我们自己写的initChannel()
二、new NioEventLoopGroup()
详情请见以前的文章:揭开BootStrap的神秘面纱
- 构造方法最终调用MultithreadEventExecutorGroup;
线程数nThreads如果没传,则设置为cpuNum*2;
children:他其实相当于线程池,存放EventLoop,类型为EventExecutor[]类型,数组大小就为nThreads; - 创建nThreads个EventLoop,放到children这个数组中
- 来看NioEventLoop构造方法:
①创建selector,selector是NioEventLoop的属性。
②将其他的值放到属性中,例如Executor等
上面的问题就得到解答了:
在 NioEventLoop构造方法的时候创建了selector
三、客户端发起请求
最终调用原生的channel.connect方法。
不解的地方:
不懂为什么要递归调用pipeline(TailContext、HeadContext)的connect方法?
四、ServerBootstrap
详情请见以前的文章:揭秘ServerBootstrap神秘面纱(服务端ServerBootstrap)
- NioServerSocketChannel的创建、服务端Channel(NioServerSocketChannel)的初始化、ChannelPipeline初始化、服务端注册到Selector与客户端过程大致相同
- 服务端有两个EventLoopGroup对象;
boossGroup-连接事件;workerGroup-io事件 - bossGroup不断监听客户端连接,当有新连接时,bossGroup就会为此连接初始化各项资源。然后从workerGroup中选中一个EventLoop绑定此连接,接下来的交互就全在此EventLoop中了
- 在启动时——bind()方法,用到的group为bossGroup
- workerGroup在哪与NioSocketChannel关联呢?——下面给出答案
问题:workerGroup在哪与NioSocketChannel关联呢?
ServerBootstrap中有channelRead方法,里面有childGroup.register(child)——child就是Channel。
- 在服务端调用ServerBootstrap.doBind方法时,会调用init()方法,ServerBootstrap重写了init()方法。
- 在这个重写的init方法里,为channel的pipeline添加了新的handler——ServerBootstrapAcceptor(ServerBootstrap的内部类)
- ServerBootstrapAcceptor的channelRead方法,在接收到连接事件就会触发,它包含了这段代码:
childGroup.register(child)...- 上述代码中childGroup就是workerGroup
4.1 handler
服务端有两个group:bossGroup和workerGroup。
猜想:bossGroup关心连接事件,workerGroup关心io事件。
关于这个猜想以后再验证
4.2 selector事件轮询
- doBind方法——>channel.eventLoop().excute()-SingleThreadEventExecutor.startThread()——>SingleThreadEventExecutor.this.run()
- 在上述run方法里,是一个死循环:轮询+事件+唤醒/休眠
- 原生nio的selector会有空轮询bug,它的selector.select()方法有问题,不该唤醒的时候有可能会一直唤醒
Netty之Channel、NioEventLoopGroup、客户端connect方法总结相关推荐
- 【初识Netty使用Netty实现简单的客户端与服务端的通信操作Netty框架中一些重要的类以及方法的解析】
一.Netty是什么? Netty 由 Trustin Lee(韩国,Line 公司)2004 年开发 本质:网络应用程序框架 实现:异步.事件驱动 特性:高性能.可维护.快速开发 用途:开发服务器和 ...
- java netty wss_netty实现websocket客户端(支持wss安全连接)
1,客户端启动类 package test3;import io.netty.bootstrap.Bootstrap;import io.netty.buffer.Unpooled;import io ...
- netty自定义channel id
netty自定义channel id.netty custom channel id 搞搞netty时发现默认的id很长,无法直接自定义. 于是我网上搜索了search一下,发现没有相关文章,那就自己 ...
- Netty应用实战:客户端重连
一.什么是客户端的重连? 简单来说,当连接中断时,客户端对运行的服务端进行重新连接. 二.为什么要客户端进行重连? 就是为了防止由于网络或其他原因导致的连接中断. 三.如何实现重连? 3.1 核心思路 ...
- python tcp服务器_python实现TCP服务器端与客户端的方法详解
本文实例讲述了python实现TCP服务器端与客户端的方法.分享给大家供大家参考.具体如下: TCP服务器程序(tsTserv.py): from socket import * from time ...
- Http协议之CONNECT方法
背景: 无意间发现自己的Fiddler有大量的Tunnel To 的host,遂产生了好奇心,点开了这个session查看一番,发现在Fiddler的详细的请求报文中和我们常见的GET和POST方法的 ...
- MQTT.fx客户端使用方法
MQTT.fx是调试MQTT协议一个必备的工具软件,这里归纳粗略介绍下客户端使用方法. 1. 下载安装. 下载安装 这个网上搜一下,就应该能找到不少. 这里提供一下网盘下载链接 链接:https:// ...
- php-redis客户端使用方法
php-redis客户端使用方法 首先配置好环境,这里就不多说了redis服务端,以及redis的PHP扩展包: View Code <?php require 'redis.php'; req ...
- SCCM 2012 R2---配置客户端发现方法和边界组
二.安装SCCM 2012 R2客户端 1.配置SCCM 2012 R2客户端发现方法 安装完成后我们打开SCCM 2012 R2的控制台: 点击左侧栏的"管理"选项,然后展开&q ...
- SCCM2012SP1---配置客户端发现方法和边界组
二.安装SCCM客户端 1.配置SCCM 2012客户端发现方法 安装完成后我们打开SCCM 2012的控制台: 点击左侧栏的"管理"选项,然后展开"层次结构配置&quo ...
最新文章
- matlab添加文件到并行池,【Matlab Debugging】使用 addAttachedFiles(pool, files) 指定要附加的必要文件。...
- Golang 匿名结构体及测试代码编写技巧
- X264码率控制流程分析
- android emmc 命令,使用CoreELEC的ceemmc工具将系统写入emmc
- MapReduce的基本流程
- java 正则表达式 html,java正则表达式语法大全
- 计算机专业Java毕业设计(项目+论文+源码)
- c语言实现双拼算法,【连载】(开始学习C语言的指针)——乐创DIY C语言讲义——6.1节...
- Django cache redis 最全介绍
- 微信小程序 实用的公告栏滚动效果
- js数组方法及返回值
- Canonical标签怎么使用,Canonical标签有什么作用?
- 【华为云技术分享】深度理解AI概念、算法及如何进行AI项目开发
- Android常用RGB值以及中英文名称
- 进程,线程与多核,多cpu之间的关系
- 网页跳转(APP内/浏览器)
- 三阶PLL环路参数计算
- 安卓Android Studio Button按钮background不生效无效问题
- jvm系列(十一):JVM演讲PPT分享
- 搭建一个代码在线编辑预览工具
热门文章
- 如何在信用卡反欺诈检测中使用人工智能和机器学习
- android65535错误实现,Android 65535问题的解决方法
- 阿里云云计算6 ECS的概念
- 价值连城 图灵奖得主Yann LeCun 杨立昆的采访 给AI从业者的建议
- 算法:动态规划 最大连续子数组和 Maximum Subarray
- 如何解决类似 curl: (7) Failed to connect to raw.githubusercontent.com port 443: Connection refused 的问题 #10
- 极客大学架构师训练营 系统架构 分布式数据库 Zookeeper 第12课 听课总结
- 极客大学架构师训练营--编程的未来 面向对象 依赖倒置原则 -- 第二次作业
- 基于近邻法的分类器设计
- java 文件上传终止_java文件上传