Netty源码分析-- 处理客户端接入请求(八)
这一节我们来一起看下,一个客户端接入进来是什么情况。首先我们根据之前的分析,先启动服务端,然后打一个断点。
这个断点打在哪里呢?就是NioEventLoop上的select方法上。
然后我们启动一个客户端。
然后我们debug看到,selectedKey的数量 = 1,说明有accept或者读写等事件发生。
接下就会进 processSelectedKeys()
我们上一节讲到,这里的attach就是NioServerSocketChannel, 我们进入 processSelectedKey() 方法
重点来了,这里对各种事件进行分发,debug看我们现在是16,也就是说是accept事件。
继续跟进去F5进去
发现进入到了AbstractNioMessageChannel的read方法。这里进入的是 AbstractNioMessageChannel !!!;
为了加深印象,我们先暂停,重新跑一个读事件
发现当前的selectKey = 1,也就是读事件
F5 进入
发现,读事件进入到AbstractNioByteChannel中,
那么也就是accept进入 AbstractNioMessageChannel , 而 read 进入AbstractNioByteChannel 中。
好了,我们回过头来继续看 AbstractNioMessageChannel 中的read 方法。
关于这个分配器,这里我先不看,待后面分析内存模型的时候再说。我们直接看下面的代码:
我们发现这个是一个循环,不断的调用doReadMessages方法,并且传入了一个readBuf,而且这个readBuf是一个ArrayList, 那这里我们猜测可能是把读取到的客户端放到List集合中保存,然后再循环处理客户端连接。
进入doReadMessage方法一探究竟。
通过工具类调用 NioServerSocketChannel 内部封装的 serverSocketChannel 的 accept 方法,获取一个SocketChannel, 如果大家还记得我第一篇讲NIO的地方Netty源码分析--NIO(一),这里应该会有印象,我这里贴出来:
这里就是获取到了客户端的socketChannel
然后这里将SocketChannel封装成了一个NioSocketChannel,然后添加到了readBuf这个ArrayList中存储。
封装这里,这里不想多说了,跟创建NioServerSocketChannel类似,大家可以去回顾一下 Netty源码分析--创建Channel(三)。
继续往下看,这里就是循环readBuf,链式执行 管道中的 handler 的 ChannelRead 方法。
根据前面几篇的分析,我们知道 , pipeline 里面又 4 个 handler ,分别是 Head,LoggingHandler,ServerBootstrapAcceptor,Tail,链式调用其中的 ChannelRead 方法,这里我们着重看 ServerBootstrapAcceptor 中个的 ChannelRead 方法。
这里为刚刚的客户端channel 添加了handler,设置了options和childAttrs,注意这里的addLast方法,并没有调用initChannel方法,具体这里添加了什么,我前面几篇有提及,大家可以再回顾一下。
接下来这里呢,就是把客户端channel注册到多路复用器上,跟服务端channel注册的流程是一样的。大家可以去看
Netty源码分析--Channel注册&绑定端口(下)(七)
我们直接说重点:
注册完成之后,就进入到了 pipeline.invokeHandlerAddedIfNeeded() 方法,我们跟下这个代码。
跟下去我们会进入上图这个execute()方法,如上图,我们看下 ctx
那么链式结构也就是 HeadContext -> NettyServer【ChannelInitializer】(我的启动类) -> TailContext
不断的跟下去,我们发现其实就是去调用当初我们在NettyServer中的initChannel。
那么也就是说,这里才是真正往pipeline中添加handler的过程!!!
神奇的是,后面还有一个remove方法。
那么这个是啥意思呢?我们再来看下ctx的链式结构
也就是说变成了 HeadContext - > NettyServer -> IdleStateHandler ...等 -> TailContext
大家发现了吗? NettyServer 还在, 也就是 ChannelInitializer 这个handler 还在链上,但是它的作用已经结束了,没错,这里删除的就是它。
怎么删的就不说了,无非就是把 ChannelInitializer 两段的链表直接连接起来,把 ChannelInitializer 剔除就可以了。
接下来就是 pipeline.fireChannelRegistered(); 和 pipeline.fireChannelActive();
就是在所有的handler中链式调用channelRegister 和 channelActive方法。
总结一下:ServerBootstrapAcceptor 才是那个负责接收客户端连接,并且将其注册到多路复用器上的核心类
那么到这里,客户端的接入就完成了,下一篇我们来看,客户端的读写过程以及Netty的内存模型是什么样子的。
Netty源码分析-- 处理客户端接入请求(八)的更多相关文章
- zookeeper源码分析之三客户端发送请求流程
znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个功能是zookeeper对于应用最重要的特性,通过这个特性可以实现的功能包括配置的 ...
- 【Netty源码分析】客户端connect服务端过程
上一篇博客[Netty源码分析]Netty服务端bind端口过程 我们介绍了服务端绑定端口的过程,这一篇博客我们介绍一下客户端连接服务端的过程. ChannelFuture future = boos ...
- Netty源码分析之客户端启动过程
一.先来看一下客户端示例代码. public class NettyClientTest { public void connect(int port, String host) throws Exc ...
- 【Netty源码分析】发送数据过程
前面两篇博客[Netty源码分析]Netty服务端bind端口过程和[Netty源码分析]客户端connect服务端过程中我们分别介绍了服务端绑定端口和客户端连接到服务端的过程,接下来我们分析一下数据 ...
- Netty源码分析第3章(客户端接入流程)---->第1节: 初始化NioSockectChannelConfig
Netty源码分析第三章: 客户端接入流程 概述: 之前的章节学习了server启动以及eventLoop相关的逻辑, eventLoop轮询到客户端接入事件之后是如何处理的?这一章我们循序渐进, 带 ...
- Netty源码分析第3章(客户端接入流程)---->第2节: 处理接入事件之handle的创建
Netty源码分析第三章: 客户端接入流程 第二节: 处理接入事件之handle的创建 上一小节我们剖析完成了与channel绑定的ChannelConfig初始化相关的流程, 这一小节继续剖析客户端 ...
- Netty源码分析第3章(客户端接入流程)---->第3节: NioSocketChannel的创建
Netty源码分析第三章: 客户端接入流程 第三节: NioSocketChannel的创建 回到上一小节的read()方法: public void read() { //必须是NioEventLo ...
- Netty源码分析第3章(客户端接入流程)---->第4节: NioSocketChannel注册到selector
Netty源码分析第三章: 客户端接入流程 第四节: NioSocketChannel注册到selector 我们回到最初的NioMessageUnsafe的read()方法: public void ...
- Netty源码分析第3章(客户端接入流程)---->第5节: 监听读事件
Netty源码分析第三章: 客户端接入流程 第五节: 监听读事件 我们回到AbstractUnsafe的register0()方法: private void register0(ChannelPro ...
随机推荐
- Qt5官方demo分析集10——Qt Quick Particles Examples - Emitters
此系列的所有文章都可以在这里查看http://blog.csdn.net/cloud_castle/article/category/2123873 前段时间去听了Qt在北京的开发人员大会,感觉QML ...
- qt线程(转)----这篇很专业!
本文档是自己所整理的一份文档,部分是原创,还转贴了网上的一此资料(已经标明了),(难点是多线程的编写),是有源代码的,大家可以作为参考,用到的知识是视频采集,压缩解压(xvid),实时传输(jrtp) ...
- Angular升级流程
执行命令 ng update @angular/cli --migrate-only --from=1.7.1 npm install --save-dev @angular/cli@latest 注 ...
- jquery动态创建小广告
<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...
- 【C#】WixToolset快速入门教程
原文:[C#]WixToolset快速入门教程 介绍 给windows系统做软件,常见的打包工具大家可能都听说过,如:大名鼎鼎的Installshield.Inno setup等.在遇见Wix之前In ...
- Windows 10开发基础——启动默认应用的URI
主要内容:通过指定的URI来启动默认的应用(设置,应用商店,地图,人脉) 方法一:直接在XAML中添加如下代码 <TextBlock x:Name="LocationDisabledM ...
- QThread的源码(直接搜索"thread.cpp"即可,或者在github里搜)
void QThread::run() { (void) exec(); } int QThread::exec() { Q_D(QThread); QMutexLocker locker(& ...
- VC++的Unicode编程
本文来自:http://tech.ddvip.com/2007-03/117395585321221.html 一.什么是Unicode 先从ASCII说起,ASCII是用来表示英文字符的一种编码规范 ...
- 使窗体拥有透明效果的API
一.背景FlashGet的透明效果大家羡慕吧.传统的Windows应用程序想实现半透明效果,一般来说需要处理自己的窗口的WM_Paint消息窗口,很麻烦.现在好了,SetLayeredWindowAt ...
- QT使用MySql的配置(使用addLibraryPath载入插件),编译QT的MySql驱动问题及解决方案(自己使用libmysql.lib进行编译mysql.pro,万不得已可以查看Makefile.Debug以解决问题)
2010/04/23:Fixes : 更新批处理,以兼容WIN7. 第一次系统地玩QT,于是诞生了此预备式: [QT版本4.6.0(VS2008编译版),开发平台推荐使用Qt Creator(最新1. ...