00:00
那这块我们现在怎么写呢,啊同学们。这个写的代码呢。这写这个代码呀,首先。我们还从服务器开始走。还从服务器开始走,因为这里面最关键点就是服务器要推送消息给所有在线客户。所以说呢,你肯定要在一定一定时候,就是当有一个用户登录的时候,是最容易,就当有一个用户登录时候,我就调出一个推送机制。就告诉你我上线了。我上线了,好,那这个呢,我们先从服务器开始写,这个代码有点多,大家看一下我的代码,这列出来就就这么多,其中有几个地方先跟他聊一聊,第一个呢。首先我们要改变的地方是哪些啊?先给他看一下,第一个,首先我们会去在这个user原先user结构体里面增加一个状态,叫user standards。这个U呢,就是代表不同这个用户的状态。
01:02
这是第一个。第二个我们要去增加一个新的一个通讯的一个消息类型,为什么呢?因为你服务器端要推送一个东西给客户端,必然要订一个协议,你不能发一个字串过来呀。所以说我这定的协议是user notify。这个message是什么呢?就是因为他是推送一个人的,所以可以很简单,就是你告诉我是谁,状态是什么就可以了。就是说你告诉我你是谁,你的状态是什么,就是相当于说我我我把我的状态告诉你。好,然后呢,这个写完了以后呢,我们写一个notify other这个方法,我们写在这个user process里面去,那么把ID给我,我就去便利所有的人看,这这很关键,这个地方我会做件什么事情呢?我在服务器称了一下,便利这个麦克里面所有的人。
02:04
然后我把我就是当前登录这个人推送给所有人,这个代码就写完了,写完这个地方大体的思路就就完事了,然后这服务器推完了以后呢,推完了以后他在哪推送呢?他在自就是当一个用户登录成功以后,我去通知所有人我上线了,那客户端这边变化在哪里呢?客户端这边的变化主要是体现在。你这推送过去,你这推送过去这个消息。应该在哪拿呢?就是你这说我推送我我在这边不停推嘛,就是notify,然后我说notify,这我我帮你了,我上线这帮不是有个right吗?那么right这个类型呢,就应该是个这样的类型,User单notify message在哪里去接收呢?我在这接收。我在这个地方,大家看在客户端这一头。
03:00
在客户端这一头,我会维护一个map,然后呢,这个地方大家看到我会写一个,这边也写一个,呃叫做呃类似于一个user m JR吧,我们估计叫user m grr,在这里面呢,我会去显显示这个,在列表这个地方,我会更新状态用户,那整个这个更新用户状态,用户就说我会接收嘛,你给我拿来过后,我就去接收接收你如果传过来一个类型是这样的类型。这个地方是server啊,同学们,这个地是server端的那一个,那个构斜程,然后呢,我发现你传的是这个类型,好我就去更新我的状态,更新一下就行了。好,思路就这样子的啊,那思路说起来简单哈,但是实现起来呢,我们要一步走来,跟着老师思路好,我们来一步一步走吧。先搞一下这边。先这边改一下message。呃,Message这边呢,我们要定义,首先把user改一下。
04:03
有时间给我们增加一个新的类型。就是增,增加一个新的字段叫用户状态。Status对不对,类型就可以了,类型就可以了,JA森总。好,User。Status。好,这个是干什么呢?这个是用户的一个状态。用户的状态。啊,他的状态有哪些,我们待会定一些常量,比如说在线离线,还有这个什么呢,比如说发呆等等等等啊这个是定的一个,然后呢,Message这边呢,我们要新定一个。要新定一个新的消息类型来,在这定,注意听啊。重新定义一个定义。为了配合啊,为了配合配合服务器端。服务器端服务器端推送。
05:01
推送什么玩意儿呢?推送这个。通知我上线的这个推送这个,呃,上线通知用户状态状态变化变化的这个消息消息消息我们新定一个类型,那这个类型呢,我们就叫这个啊叫type叫notify。Notify notify。啊,Status status。呃,这个user,呃,Standard standard啊,Message啊。通知用户状态的一个message消息,那么它是一个结构体。Tru。好里面呢,我们认为至少要有两个字段,一个字段呢,就是这是哪一个用户,所以说呢,第一个字段UID,注意听啊有有点难度,但是呢很有意思。
06:05
你们一定要记住啊,一个东西如果特别简单,一一学一一上来就能搞懂的,那一定一定不会特别的有用啊好,这个是用户的ID,这个我不说了,就是用户的ID,那同时呢,你还要记录一下用户的。这个他的状态user,它的状态,它的状态是什么呢?呃,Status。Stands OK,也来一个英特尔吧。好,杰森走。Standards,我sorry,慢点喂。好。电视。好,我接着讲啊,我接着给大家看,那这块呢,就是我们用户的状态。
07:06
用户的状态。那有了这个用户的ID,又有了这个用户状态呢,我们这个地方就应该定义相应的一个类型。他这个没有没有回应哈,没有没有想,就是我直接推给你,推给你好,那有了这两个东西过后呢,既既然有消息了,你就得定一个这样的对应的类型,这个是我们以前老规矩,老规矩。但大家可能想,诶,那你这个notify推送功能有没有响应呢?也有可能有,但是现在我们不需要啊,因为它是它现在是服务器发发发起了一个主动的一个推送,他不像我们前面这个注册和登录,是客户端发一个请求,说我要干什么,服务器送啊,你的结果是什么?他现在是服务器那边主动推送的一个东西给我们的客户端说诶我要干,你这就是主主动推送。好多同学可能听过这个概念,现在终于见到了,这个叫主推,就是服务器推个东西给你,你看你为为什么有些同学上这个微信,上了QQ,你上去过后,你会看到有些广告啊,有些什么东西,其实是服务器推给你的。
08:13
他可以推广推过来的,好,那现在呢,我们就呢,就相当于说推送了一个用户的状态的message,好没问题,我写到这里写个type。好的,那type呢,这边我们整体往这边挪一下啊,把它对齐,然后它等于什么呢?各位朋友,它就等于这个message类型。啊,这是type类型,这是消息类型,好写完了,那这块写完了过后呢,呃,这个定定好了以后,下一步呢,我们就来开始写,在这边写两个特别重要的方法,这两个方法呢。要看看大家能不能绕过来啊,就你现在任务是什么来看这里。找到我们服务器端的这个user process。因为他是专门处理用户相关的,大家还知道我曾经在这个上面写过一句话,我说我说了这样一句话,我说将来这个user process是处于登录、注册、注销,包括用户列表管理,我当时应该就写到这了。
09:16
那不是乱写的。就说你将来这个用户列表管理用户状态,你是跟用户相关的,你就是这那一会儿我们写群聊和点对点聊天,我们就写这。当有些同学说我还想写一下,发发图片,发文件,发视频,你再给我写新写一个叫VIP啊,你你用那个东西来写,处理这个东西,大家各司其职。好,现在既然如此呢,我们就在这里面写这个东西了啊看代码开写,找这我们现在开始来写这段代码。好,来写一个代码啊,这里。这里我们编写编写通知,通知所有的人,通知所有通知啊,就是编写通知所所有在线,所有在线的这个用户。
10:10
用户的一个包啊,用户的一个一个一个方法,那么这个方法怎么写呢?当然按照我们思路来说,就应该是这样写this轴user。Process。那这个时候我们写的方法应该是这样,是notify notify other。就是其他的人,那他自己不用通知自己啊,说老师我自己你自己上线了,你还通知自己肯定没有道理嘛,所以说这个就others,哎,Others通知其他的人,我的一个状态通知其他人啊,通知其他人,其他的user online online。Online。On online有。好。好,那其他其他同事其通知其他这些人呢,那我怎么通知呢,我怎么通知,因为这边已经有连接了,我要通知的时候呢,其实就是通知我上线。
11:11
那你这边要传一个什么东西过去呢?大家可以想一下。对,我要通知的就是有一个人上线,我这里面呢,可以便利,在这地方便利就行了。啊,便利。我们先写到这,这个参数是什么,我们现在还想不起来。我们待会再说啊,因为你你这个地方是别人上线了过后,其实就是一个人一个人的状态,一个人的状态,所以说呢,我们先写到这,这样是啊便利。他在这边就便利什么呢,他就哦对,他必须要传一个ID,我现在想起来了,应该要传是这个刚刚上线这个人的ID。对,他有一个这个这个信息,就是说这里面呢,他要相当于说这个人。这个人要通知其他的人物上线了。
12:00
这句话应该反过来看啊,就这个人。这个ID要通知,要通知其他的其他的在线用户,在线用户我上线了。我上线。我上线,可是你要通知其他人上线,你能便利,这个欺骗你的便利什么呢?你要便利。你要便利这个user。User manager里面的这个这个东西要便利他说,说白了,你你是要便利他。要便利它,然后一个一个的发送。然后一个一个的发送,然后注意听,然后。啊,然后一个。一个。一个一个的发送。发生什么呢?你一个一个的发送这个消息啊,就是刚才我们定好这个消息。
13:02
你要发送的是这个消息,就说哪个人上线了。要发这个消息过去。好,那现在就简单,那就负循环。那你负循环的时候呢?For循环的时候,你就可以把这个呃,这个map,这个online里面的拿到它里面有一个ID。ID同时呢,同时呢,还有一个对不对,它还有一个什么呢,就是。他还要取出一个up。这个up就是其他人的这个这个user user process啊好,这个我就遍历了,等于range。好的,那我取的时候就是this里面的online。昂来有人。Online users users,好,这是它的一个map。那取的时候呢,我们有一个地方不能发送,就是自己不用通知给自己,先把它去掉,过滤掉自己。
14:04
过滤掉,过滤掉自己,因为你自己给自己发没有意义。你你上线了,难道你自己不知道吗?你肯定知道,所以说你不要发给自己,那不要发给自己怎么办呢?好办。就是如果你这个ID就从这个,从这个整个这个map里面,因为这个map大家都知道它是长这个样子的,这里面肯定有你自己,你上线肯定要把服务器要把你自己扔进去,所以说呢,这个ID如果他等于了你这要创要通知的这个人。这个呢,就是刚刚上线的啊,这个是你遍历出来的。啊,如果他等于自己了呢?好,我就不去处理。Continue。好,那如果说他不是自己怎么办呢?那就开始一个一个通知了,好,这时就可以通知,就是开始通知。那么因为你是开始通知的话呢,同学们,如果我把代码直接写到这儿,感觉很乱,所以说我们单独的写一个函数。
15:05
我单独的写看书啊,单独的写一个方法。那你单独写一个,方法也很简单,就在这写就行了,放。这样写啊。啊。然后呢,认识行还是把这个方法关联在user process里面上。好,这个写完,同学们有个好处啊,你们想写很多功能,可以自己有思路的,绝对是这样子的啊,我就这样写,Notify。密呢?通知你,我上线了。但你可以这样写哈,说老师这个名字写的能不能在高级一点就通,Notify me to other也可以。因为这样的命令方式也没问题啊,就说not notify。通知我给别人啊,这个就感觉怪怪的啊,咱们就去简写吧,Not notify me online就是通知我上线了。
16:07
那你给谁给谁通知呢?好,各位同学好,写进来这个地方啊,有点绕,就是你因为你现在已经拿到这个up嘛,这个连接你你是有的,所以说。这个是取出来连接,那你就想办法做呗,因为你现在这个自己这个ID是已经有的。好,这是你要通知的,所以说这个是还是可以付过来。还是可以复过来,你在这传的时候就应该调这个up了啊同学们不是这次了,你你可以这样理解,你可以这样理解,这个是取出来的一个user up。啊,You up,我们看看应该怎么调啊,同学们啊,对,是这个意思。因为这里面是各个的,这边是一个一个的up嘛,我相当于是这样子的up点。
17:01
就是说他自己有个方法,Notify。然后呢,把你取出来的,因为这个up就是每一个人对应的。每一个人对应的那个APP嘛,就是就是这相当于是这个东西,相当于这个东西。也就说我已经拿到,比如说我我是量打个比方,比如说是有一个人。假设有一个人是300毫升线了。三三百毫升限了。那你300毫上线过后呢,他拿到了一,他从这个100号的not体法,就是说通过这个not体派去通知300毫上线了,他他他给这个人说300毫升线了,明白这意思吧,好,那现在呢,这个逻辑就是这样子的,我把这个UR传进去。邮件传进去。好,那传进去过后呢,你这边要做一件事情,就是想办法把这个UID通过。
18:00
通过这个Z传进去,这有有有人道啊东西,听你这传进来这个Z。是当前这个用户的,就登录这个哥们儿的。那个。有点process,但是等到你便利的时候呢,你这个up这个地方的认识指向是各个。在线用户的那一个process,因为你你在里面做了一个便利。便利好,这里有稍微有点绕啊,注意听好我写我再写下来,写下去,好写到写到这个地方呢,大家都都很清楚的说,哦,Up传进来了,Up传进来过后呢,它就有了,这个是每个用户的在线用户的那个就是好,那现在就开始组装。开始组装。组装。啊,组装什么呢。A。他就组装。组装我们的这个消息,Notify这个消息啊,好,我把这个拿过来。就是组装这个消息。
19:02
那么这个消息怎么组装呢?老规矩仍然是一样的,来VR这个消息是一个一个的整出去的啊,那就是message,等于。那么这个地方类型呢,就是message里面的这个最大的外层的这个message。看大家还记不记得mes age它的类型,Me d它的类型,Type它的类型呢?就是这个类型,就是刚刚我们定好的类型。就这个类型,因为服务器的客户端将来会拿到这个消息去解析的,所以说呢,这个地方我们就拿到它的类型了,那应该也是message这个包包里面的啊。好,这是一个,接着继续往下写。你有这个message没有用,还得有一个东西,就是它本身这个message里面的实体,所以说还要做一件工作干什么呢?再创建一个这个东西VS,比如说我们现在返回的是这个类型。
20:02
是这个消息。好,Notify us,这个这个东西。好,我就写到这里啊,为了简单一点呢,我这边写个小写的N就可以了。好,然后这边同学们稍微慢一点,Me点,大家看懂了。那这里面的消息呢,就是我们真真真正他关心的消息,那就点首先把它ID传进去。是哪个ID?就说这个人上线了,这个人。这个人上线了,就他他上线了,他的状态是什么呢?他的状态。那显然目前是上线,当然也有可能将来是离线,也有可能是发呆啊,我现在写的是一套这个,这个时候好给他来一个点什么呢。好,给他来一个这样的点,就是他的状态status。等于多少呢?好。好,这个时候需要我们再定义一些常量。
21:03
因为你这个在线离线呢,我们也没有必要写一个字算我们写写个常量,那在哪定呢,注意我简单一点啊,直接在这定一点东西。我在这儿顺带定义几个用户在线的状态。这里我们定义几个常量。注意听。好,我就直接写到啊,这里我们定义几个几个用户,用户在线的用户状态的。状态的常量,大家可以看到这个代码呢,确实有点。就东写写西写写啊。我告诉你,其他老师这写已也是一样的啊,就是你工作有多少年的,有个23年45年的,你在这写已已然是这样子。好,那这里写呢,我们就写个user,比如说user user online。又是,嗯,难。我就这样写啊。有online,那么我给他一个值,比如说是零吧,有些人喜欢这样写IO托。
22:06
好写这个,然后下面生长也可以啊,比如说user,一个是上线,一个是离线。User ofline。当然,你你后面可能还要加很多东西了,Of。Of。And。那么这样写就可以了,诶这个不用写东西了是吧。哦,都不用写,它自己往下增长,那也有可能同学还要相信,诶,繁忙,比如说user busy。By standards。比如他一个繁忙状态,当然还有可能是,呃,你看那个QQ里边还有比如说吃饭去了啊,我不搭理你等等,你们自己可以往后面自己自己整就行了啊,我呢就写写这么几个四个一就可以了,这方不是大括号,是小括号写错了,刚才。好,这样子呢,我们假设现在状态呢,就是user online,那我回到这边把它写进去哦,它的状态是message包包里面的这个状态。
23:08
好了,同学们,这个整完了以后大家知道。Notify的时候呢,整完了以后,我们要把它序列化。将将谁序列化,先将它序列化。序列化,好,这个序列化对我来说太太简单了,我们写了好多遍,L等于。等于等等于什么玩意儿呢?好,就等于我们的Js.Mar。走包起来,然后这边我们写的是针对它进行一个序列化。好,序列化完了过,如果有错,我们就直接报错,不走了你。好,直接。提示一个错误信息。对,提示一个错误信息,比如说这个,呃,就是序列化出错,就是在notify online的时候序列化出错。
24:02
就直接写个序列化出错吧。好的,然后呢,咱们把这个错误信息打出来。最后下面就不走了,因为你你已经不能完成序列化,你肯定走不了。紧接着还要做一件事情,不要忘了,你现在是只是把谁序列化了,把这个notify message本身序列化了,但是你还没给他,因此第二步将这个data付付给他,好,这个大家应该还还有印象啊,就是把这个data给他,但是data呢,是一个BY的切片,你要转成十寸,这个以前我们写过好多遍。好,这个相当于说把我们的这个给将将序列化的啊,将序列化后的这个message。这个message付给啊,付给了谁?付给。赋值给赋值给这个data,好同学们认真听啊,就这个还是很有意思的,你你把这块突破了,我们可以这样讲,你后面想扩展一个功能,很简单,就说你要群发点对点聊,我们后面马上把这写完,我们就是聊天。
25:12
周老师你你讲的这个聊天,怎么你讲到现在还没聊天,还没开始聊呢。不是这样子的啊,就说有些准备工作上很重要。你在线用户都拿不到,你跟谁聊,那你只能是群发那个电视太小了,可能没没法玩那东西啊,写的很简单,比如说哎,我学个东西给你发个那个东西没有一点意义,对吧,一点结构都没有,随便增加一个功能都跑不起来。好,那付付给他过后呢,你还要对他再次进行绝对化。这个大家应该能反应过来,因为MS仍然是个结构体啊,它是不能发的,好,我们对它再次进行虚化,对,对神经虚的话,对这个message再序列化。再次序列化。准备再次序列化准备发送。
26:00
就准备发送了啊,我们快快快OK了,服务器端快OK了啊。准备发送,怎么发呢?非常简单,那就是序列化,先把它拿过来复制一份扔这,然后呢,把这个地方换成messages就可以了。其实大家看到这段代码没有必要,大家如果动脑筋的同学其实已经看出来了,说老师这段代码不是,你反正都是把这个人通知给N个人吗?你把它写到这点不是很不划算吗?的确,如果你看出来这个东西的话,说明你稍微看的有点懂了,因为因为目前我们是要把这个人的状态通知给所有的这个其他人,因为upper每次取出来是不一样的。其实这个玩意儿,他永远对一个人来说,他。你做了好多次,假设1000个,你就搞了1000次,肯定不划算,对不对。但是呢,我们后面再优化,就这段代码,其实可以把它拎到外边去。
27:00
拎到外面去对不对?好,但是这个思路大家先先把它看清楚,我们这会把它提出去就行了,单独写一个函数嘛,叫封包,然后一下就搞定了,好,这个做完了以后,我们下一步干什么呢?我就发送。怎么发送呢?因为你这方已经拿到了它注意啊,这个地方这个Z就代表这个up。就是从你从那个map里面取出来的那个那个那个有带连接的那个up,好这就发就行了,好up对我们现在发送还不能靠它,还得用这个创建啊,创建我们固定的东西,创建我们一个transfer磁力。Transfer实力。川分的一个实例发送。发送。那么这个这个TRANSFER1011呢,我们是这样子见过的就是U7。U u tea里面呢,有个穿缝包起来,里面有个。
28:07
好这个呢,诶刚好就是我们这个带过来了,这一点马上匹配上,就你这个this里边是带一个的点完事。好了。然后我们就通过这个ttf发就一下。Right,什么PKG把什么包包发出去,就把这个data给他发过去,当然这边有可能有错误搜一下。如果我们发送出错,我们写一句话就行了,如果L不等于零。就说明我们在通知。别人通知消息的时候发错了,有出错,Print print。好,我写一句话啊,叫做什么呢?叫做这个notify online的时候,Notify me online的时候,这个出错了等于什么呢?写完了最后返回。
29:00
返回过后下面不走嘛,相当于。哎,最后就可以了啊,因为这段我没有返回值,所以最后这个呢可以不要。我问,我请同学们思考一个问题啊,请在听课的同学思考一个问题,哎,这么包留错接上包包没有引进去好的这个地方那应该是有问题啊,待会我们再诶接成宝宝引进去了。杰森,哦,有的有的上面已经定过了。这是一个。上面这个message呢,是因为没有以message。好,他说没有定义这个东西,是因为我没有整体保存。好,我整体保存一下。OK。好像没事,好像没事,因为当时呢,我改了一些东西嘛,这边没改好,请同学们思考一个问题,请同学们思考问题,说老师。你刚才说的这段代码。就是这一段代码,它实际上永远都是同一个带,就相当于说你有一份带要发给十个,20个,100个,这个你可以把它提出去,这个没问题,那么我想请同学们思考问题,这个能不能提出去呢?
30:13
川十分能不能提出去呢?说老师,我们用统一个题,统一用一个川十分不就完了,你每次整这么多川十分干啥?如果这个东西你敢提出去,我告诉你,你就发给一个人的,你永远只发给一个人,其他人傻傻在那等着,不知道,因为这个康是不一样。因为你这个this每次传接这个APP不一样,这个this就不一样,这个传输就因为你最终是实现目的是要把这里面的看拿到一个一个的发。所以说这个地方是绝对不能提出去的啊,这段代码你要提出去,你会发现只有一个人拿到这个推送消息,其他人全部一个消息都拿不到。但是这段代码就是我学的这段代码可以提出去。待会儿呢,给大家这个任务,你们提怎么提啊?放到哪个位置比较合理?其实非常的简单啊,动动脑筋行好发出去了。现在我们历经千辛万苦,这个。
31:06
发送代码写完了。那么写完了过后,你在哪里去调这个方法比较合理呢?在哪里去调这个方法比较合理呢?动动脑筋好,因为我现在已经编写了一个一个用户上线过后我就通知他,那显然这个的调用应该放在这个用户登录的时候,登录成功或者他状态发生变化的时候。去调用,现在我们因为只有一个在线和离在线,我还没写离线,离线很简单,就说注销的时候,比如这个人注销之前,他退出之前,他按下就注销,或者退出之前,或者我检查这个连接没有的时候,我再去把它状态改成离线就完了。好,现在呢,只有现在只有上线,所以说这个函数的调用就是函,就是刚才我们写的这个函数的调用呢,就应该放在。登录成功的位置即。这个位置。
32:02
所以说大家看这个难度啊,是有一点大。确实是有一点大啊,就是可能一时半会都跟不上思路了,我就直接扔,这就完了。我用U这个地方,因为它这个no notify other online user呢,它是属于这个这个这个管理的,说直接用this调就行了。大家看清楚了啊,认点他,然后把你当前用登录的这个家伙的ID传进去,登录这个家伙的ID不就是他吗。好,完事。这句话看起来很简单,就一句话,但是我们写了好多代码。这句话是通知,就是当,就是通知其他的用户。用户什么用户呢?就是在线的用户啊,其他在线的用户。在线的用户我上线了。我上线。好,完事。
33:00
好,你看这个代码呢,就很OK了,就是上来过后,你们能想象到会出现一个什么情况啊,大家可以想象这样一个场景,就是有一个A客户端上线了。有个AA客户端上线了,这个家伙一上线过后呢,假设下面这儿还有几个,嗯,几个客户端,比如说是还有C客户端,D客户端,我就不写了,这些客户端呢,也在这假设有一个假设AB已经上线了,C1上来。C1上来一成功过后呢,他把自己也先加进去了啊,相当于说这个这个map里面已经有A和B,然C1上线呢,他就服务器就便利了整个这个map,然后呢,把这个map里面的康莱达通过通知A和B说C上线了。C上线。那当然了,你你这块代码就说服务器端的代码呢,你就显然在这调一下就就完事了,就说你这调用就可以了,代码,服务器端的代码就写完了啊,服务器端的代码就写完了。
34:03
那服务器代码写完了过后呢,我们先把这个先截段视频。
我来说两句