00:01
China handler context。这个组件我们来看一下。China handle contact,它保存了China相关的所有上下文信息啊,同时呢,它还关联了handler,也就它会关联一个China handle,就跟我们前面画的这个图一样,对不对,我们整整个派online呢,它是一个双线链表,双线链表呢啊,它你可以认为每一个节点就是一个China handle context,而每一每一个handle。呃,就是China handle contact呢,它又关联的一个China handle对象。啊,即怎么去理解呢?就说我们这个China handler context中包含了一个具体的事件处理器handler,同时呢,这个China handle contact也绑定了对应的pipeline和China信息,方便对这个handle的调用。那现在呢,我们还是用debug的方式跟大家加深一下对它的认识,老规矩我们在哪哪里加深呢?我们就在这吧。
01:06
对,呃,待会呢,我们把断点下在这,对,然后呢,待会我们看一下这个ctx,就是China handle contact,它到底是不是包含以下信息,对,好的,我们先来DEBUG1把。运行。对。那运行过后呢,我们这样子哈,我们这边还是回车,那回车呢,断点就会定在这个位置,对不对,定在这个位置呢,我们来看一下ctx,首先我们看它的类型。就是ctx真实的类型呢,其实是debt China handle contact,因为本身handleler,呃,China handle contact它是个接口,所以说b China handle contact它是才是它真实的。类型,那首先我们看是不是有个handler,那我问大家现在这个handler为什么是test http server handler呢?因为你现在已经进入到该handler了,所以说这个时候,此时此刻这个ctx。
02:08
它关联的handler对象就是test htp server handler。同样大家可以看到它可以通过next和pre呢,可以往就是继续去找查找他,其他的这C我们来看一下,比如说大家看。它的next,嗯,它的next下面呢,已经为空了,没有了,那么我们就往前找,为什么它是为什么这个地方next为空了,是不是因为我们这一个test htb server handle是我们加在最后的一个last,最后的执行的一一条语句,所以说我们要看的话呢,应该往哪看呢?像这个。大家看这个pre,也就这个这个contact的前面呢,又是一个debt China handler,而这里面又关联了一个handler,这个handler就是http server口袋。是不是我们在前面那个代码写的,我们先加入的是htp server口袋这个handler,再加入的是test htp server handler,因此这个顺序呢,就是保持一致的,好的好,同学们,那这就是我们所说的,呃,它包含了一个handler,那同时呢,我们看它还关联了pipeline,就是我们的所谓的。
03:23
管道对吧,他把这个管道也关掉,那有些同学老师你刚才不是说还有China吗?China在哪里呢?大家看通过这个pipeline呢,我们其实也可以拿到China。对吧,所以说就证明刚才我们所说的这这样几句话是什么呢?就是。一个context,它包含了一个具体的事件处理器。啊,同时呢,他还绑定了对应的pipeline和China,那你要获取到有些同学老师我能够获取到pipeline China,还有它对应的handler吗?当然是可以的,来我们看一下。比如说我在这里哈,给大家看一下。
04:05
我们输出一下。它对应对应的这个China,你是怎么获获取呢?非常的简单。Ctx点我们的排。哎,你看他直接其实他就可以直接去获取了,看到没有。直接就可以获取了,不需要绕,那么我们再来获取到什么呢?再来获取到它对应的pipeline。Pipeline怎么去获取呢?加。就是ctx点。是不是?是吧,就说你从这个ctx China可以拿到这个PI呢,也可以拿到,那当然有些同学老师我这样拿到他们两个是不是同一个China呢,也可以试一下啊,我们通过另外一种方式获取。呃,怎么通过China,通过这个pipeline来获取pipe。
05:04
Nine获取什么呢?China?也可以这样获获取,我们看一下ctx点点China。其实这两个呢,你不管是这样去获取,还是这样获取,其实都是一样的啊,其实都是一样的啊,那现在呢,我们再来看一下,就是如果我要获取到当前的它的什么呀?它的handler可以得到吗?对应的就是当前的吧,当前ctx的handler我们可不可以拿到呢?当然也是可以拿到的。来看一下。怎么答案呢?CTx.handler就可以了。对不对,同学们好,那么我们来运行一下看看是不是,呃,确实是可以拿到的,那我们先把debug停一下。第八个停一下来,同学们,我们运行这次就直接运行。好的运行。
06:02
OK。运行运行到这边简单,我们直接刷一下新。好,刷完过了,我们来看一下啦,我们来看一下。同学们可以看到,嗯,从这边信息打出来对应的China。啊,因为我这发出两次啊,发出两次对应的China,我们一个看。呃,网网站上网上找一个吧,找一个。对应的China呢,它的ID是这个。对不对,0XF48什么什么什么一堆pipepeline pipepeline这个类型呢,是deat China pipeline。对,然后他这里面还包含了很多信息对不对,看到是不是他有他下一个,他下一个是谁谁谁啊,我们都可以拿到的,比如说拍PE烂,呃,他的信息往这往这找吧。你看这两个是一样的吧。我们直接获取的channel,它的ID是他。我们通过pipeline获取的China呢,ID是不是也是一个呀,0XF48288B4一样的。
07:07
对,而且呢,我们可以看到也能够获取到当前ctx handler是哪一个呀?是这个是不是就是test h DB server handler。是不是这个,诶完全的OK,完全的OK,所以说我们这个ctx呢,其实是可以拿到很多信息的。接着继续往下看。那关于。这个China handler contact呢,它还有很多方法,比如说close flash right and flash等等,那么close呢,就是关闭通道,对,然后这边flash刷新,还有一个right and flash呢,它可以将数据写入到China PI line中,当前的这个handler的下一个handler开始处理出战的形式。也就是他这个可以把数据继续往下流动。好的,那关于这个China handle。
08:01
Handle contact,我们就说这,下面我们再来看China option net在处理China实例后呢,一般注意他说的是一般,你说不一定非要设计,也有默认的设置,一般我们可以去自己设置相关的参数,嗯,有两个参数需要大家知道一下,我们也用过。大家还记不记得我们在这边写的时候呢,老师在这里。在这个option的时候,我们设了一个option里面一个so so backlog,那这个参数到底代表什么含义呢?它是对应TC bib协议listen函数中的。Up。这个back log参数用来干什么的呀?用来初始化服务器可连接队列的大小。为什么要设置一个队列大小呢?因为服务器在处理客户端连接请求的时候,它是顺序处理的。所以同一个时间呢,其实只能处理一个客户,客户端连接多个客户端来的时候呢,服务器将不能处理。
09:04
啊,就是如果你同时来的话,服务器端将不能处理的客户端连接放在一个队列等待,那么这个参数就可以指定我们这个队列的大小,对,那还有一个叫so keep alive,这个是指我一直保持连接的活动状态。好,这个China optional我们就说到这儿,下面我们再来看一个重要的东西,叫group。它以及它的时间内叫nio event group,呃,Lo lo group,那这两个呢,我们现在从源码看一下。从这里看一下event,我们哈,Even en event,然后是lo什么呀,Group group。好,我们可以看到它呢,实际上是一个接口,而且呢,他还继承了even even的ex,呃,Exor group,也就是他还继承了事件执行组。
10:04
那就说明我们整个这个呃组的呃,就是我们这个loop,呃loop group在执行的时候呢,跟我们执行器也是有关系的,对,那现在我们来看一下。我们来看一下它的一个关系哈,往这搂。我们可以看到。这是一个接口,那它我们这里面用的比较多的是哪一个呢?真实的这个N,它的这个实现子类其实是n IO event group group,我们找一下在哪里。是不是在这啊,大家看你看这里。Event group,然后呢,他又继承了这一个。Group对吧?那现在我们就来看一看,就是它这里面有什么相关说明的event event lo group呢,是一组event loop的抽象ni为了更好的利用多核CPU的这种资源,一般呢会有多个event lo同时工作。
11:04
每一个loop维护着一个select,是不是前面我们已经说过了?而且呢,这个lo group呢,它提供了一个next的接口。可以从主理按照一定的规则获取其中的一个1EVENT loop来处理这个任务。那么let在服务器端编程的时候呢,一般我们去提供两个这样的这个线程组,就是group group,那么一个是boss,一个是worker,是不是已经说过了,好,现在呢,我们来看一下一个示意图来再次说明。通常一个服务器端口及。及一个server呢,对应一个select group,这个呢,就是可以理解成这是我们的boss。Bosch group。它呢,一般我们会起一个啊event loop在这里进行一个监听,Boss event loop呢负责接收客户端的连接,并将生成的这个so China交给这个worker event group lo group来进行IO处理,也就是说他这边就是我们这个boss group在这边有对应一个,一般是对应一个,当然也可以有多个啊,有一个event group在这循环。
12:17
对循环,那么循环过了呢,我得到一个China so,实际上是得到一个shock的shock的,呃,China,然后呢,选择。其中的一个LA就是worker event lo group的其中的一个event event lo来进行这个服务。哎,服务,但是他在做的时候呢,他其实按这个next的方式来走的,大家还记不记得我们以前讲过,如果我们boss group只有一个event lo,而这边有八个,是不是就是next,它是按照这个默认情况下是按照什么呢?按照选第一个,再选第二个,再选第三个,以此类推,选完了后再进行一个循环。是不是这样子的,那么我们可以再来证明一下这个观点啊,就是把刚才呢讲的这些东西,讲的就是它里面包含什么什么什么,再给大家搂一遍,用代码的形,用这个debug形式,再来看一下,来走一个。
13:14
呃,这时呢,我们选simple来演示哈,把这个关闭。把这个关闭,我给同学们做一个测试。我给同学们做一个测试哈,嗯,怎么做呢,大家看。我们把原先的把这个simple里面的server handler。呃,前面这一部分不要的,先注销一下。这是我们原先加的。自定义的普通任务是不是先把注销,因为待会儿呢,我想看一下。看一下他的,呃,这个规则就是next规则,到底是怎么玩的?我得打开。好吧,我把这个打开在这里呢,我们可以看到服务器读取线程的时候呢,它会把这个现程的名字拿到,那就是实现现在看到是到底是哪一个线程为我们服务,那么为了看到这个效果呢,我们干脆把当前这个China的China的信息也拿到。
14:11
就是看看是不是每一次对应客户端对应的圈也不一样。China等于来走一个,那就Ctx.China。好吧,把这个学X也拿到好,同学们,现在呢,我们就准备来测一下,看看这张图怎么体现。首先。呃,首先大家来看一下,在这里呢,我这个server指定的是一,就是这个boss group指定一,说明目前boss group里面只有一个event lo没问题吧,待会你们可以看到这个代码这个效果,然后这边呢,有八个,默认情况下是不是起八个呀。为什么是八个呢?因为它其实是我们CPU的核数乘以二。好,我先把这个断点挂这。挂这好,我们来DEBUG1把。
15:01
第八个。Debug过后呢,我们先证明他们之间的关系,就是group和group之间的关系,好的那同学们可以看到哈。我把这。光标停到这,看boss group里面,下面呢,只有一个China child是IO event loop就是他在这里不停的循环。好,我们再来看worker group worker group呢,大家可以看到有八个,对不对,有八个IO的group。啊,大家可这编号呢,也看到的确是不一样的,好这一点就OK了,也就是说现在我们解释了,解释了这个图的大概就是说这边呢有一个event loop。这边呢有八个,那现在假如我们这边有八个,呃,或者是九个吧,九个客户端来连接,我们看看这边他在这个这个机制在进行next的选择,它多个event loop的时候,它的规则是什么,同时我们我们可以看到,呃,就是是不是一个event loop可以对应多个客户端,或者说对应多个China的处理,我们来看一下好吧。
16:06
同学们,现在呢,我们这样子做了,刚才呢,我已经在这里加了几句话,是不是这是我们的一个。呃,就是server handler,那我在这运行的时候呢,大家可以看到这个server handler呢,就在为各个不各个这个呃,客户端进行服务。各客户端进行一个服务好的,那现在呢,我们来运行一把啊,运行一把,看看是不是这样子的让一下。让一下。好让起来。过后呢,同学们,现在我。运行这个客端。运营客户端。运行后端,好,同学们看,第一次来了,第一次我们可以看到呢,在这里哈,咱们看。读取线程,读取线程是。这里面的分配的三三杠1CHINA,现在是这个这个ID好吧,好,我们再来起一个,我们多起几个一次性的,现在就直接点哈,第二个。
17:10
第三个。第四个。第五个。第六个。第七个。第八个好的,现在呢,我已经有八个了,我们看服务器这边是不是这样子的,那没有到八个,123456才六个,还没有到八个再来。第七个。第八个好的,来同学们看。好,同学们看第一个,第一个来的时候呢,是三杠一,他的是。ID是这个第二个是不是他的ID又变化了,说明你说明现在这个第二个线程为channel服务的是这这个channel第三个来了,三杠三是不是又变一个channel,因为你客户端不一样嘛,当然每个客户端对应的channel是不一样的了,三杠四是不是也是一样又在变化三杠五是不是又变化了三杠六。
18:09
三杠六是不是又到这来了,三杠七又到这来了,三杠八又到这来了,现在呢,我们再看三杠九,看他现在已经轮训了一遍,如果我再来一次,大家觉得会怎么样?运行,当运行过后呢,你们会看到啊,同学们可以看到这边呢,又变成三杠一了,因为你三杠八这八个线程已做完了,下一个就轮巡一圈就变到一了,而且大家看这个时候。嗯,虽然这个也是三,这是三杠一,但是这个China并不是跟你第一次的这个China一样的,你看第一这个,嗯,三杠一第一次为哪个China服务呢?为这个China服务是0X6A这个时候。他服务的是0XA8,显然不一样,为什么呢?因为你的客户端不一样,所以说从这地方我们就可以证明,其实你这个event loop可以为多个China服务,而且它的机制next呢,是在按照我们这个规则进行一个允许,对吧?默认是这样子的,好,我们再念一下这边的文字就可以了。boss event loop group通常是一个单线程,当然也可以是多的。
19:18
呃,单线程的event loop event loop维护了一个注册server softwareer China的select,这这是不是就说我们每一个这个event loop里面都有一个select,是不是前面已经讲过这个事情了,就是就是说你这里面有个select。它会对应select,它有个S。Select,那下面这个呢,诶也有他自己的select。并不会共用啊,这个呢,又有一个,那你这是不是也有呢,当然它也有select。明白这个意思啊,所以在这点大家一定很清晰,然后呢,通常情况下我们这边。
20:01
就这个boss问的loop呢,他只是通常去处理啊,他只是去处理这个accept事件,然后将接收到的soet China转交给谁啊,转交给worker的group group去处理,他呢会根据他的这个规则,因为这个家伙呢,他有一个next方法,大家看一下。他有个Lex方法,我们看看。哎,看这里啊,呃,Loop group,我们看看有没有这个方法。好,这里没有,没有的话呢,我们到到他这个上一区去找。上去了,他肯定会实现这个方法,诶找他找他。好,同学们看这是不是一个next方法呀,这个next方法,因为你下面的子类实际上都去都是需要去实现这个next的,所以这个next的这个方法就是用来去规决定到底是下一个,下一个选哪一个even的loop为他进行服务啊,为这个就是来的这个S进行服务。
21:01
好,你看我这写的worker event group group,会由next选择其中的一个event group,呃,当然这个写错了啊,选择其中一个。Event loop来将这个shocket China注册到注册到其维护的select,并为后续的IO事件进行处理,因为你这个下面管理的其实已经是event lo了,对吧,不再是group了,这样的一个关系,好的,你看这个地方返回的我们看是不是这样子啊,你看返回的也是一个event lo,而不是一个event lo group了,所以说这面应该是写的其中的一个event lo,好吧,好的,这就是他的,嗯,这个规则,最后呢,还有一点再说一下。就是这个它常用的方法,一个是构造方法,另外一个就是我们用过的shut down Grace,就是断开连接,关闭线程在哪里呢?我们在这里其实也用过。找一下。好,我们在这找到,是不是在我们。
22:02
Server这边。如,最终呢?如果是,呃,我们要关,如果说不管你这里是什么情况,Finally,最后我们需要干什么呢?Shutdown graceful就是关闭。干什么呀,就是断开连接,关闭线程两个任务啊,一个是断开连接,第二个是关闭线程,好同学们,那关于我们这讲的这几个东西呢,就聊到这儿,一个是讲了。Handle contact,另外讲了是China option,还讲了非常重要的event group group以及它的实现子类,还有呢,就是它的一个工作的机制。好的,那关于这块我们提前聊到这里。
我来说两句