00:00
大家好,在上一节课我们完成了消息的发送功能啊,然后其他的客户端也能接受的消息,那么这节课我们来写一下私聊的功能,私聊的功能呢,我们就做的简单一点啊,不再是说点一个人再谈一个这个窗,新的一个聊天窗口什么的,我们就点简单的啊,点击某一个人能在这里啊,出现一个艾特谁,然后是一个私聊的一个状况,那这样的话,我们在发送消息的时候呢,只让我们艾特的这个人收到消息,好吧,那我们先把前台的JS给写一下,因为这块之前没有写啊,那我们首先要给一个啊,这边点击事件,点击之后呢,我们要让这个人的相关的信息显示到这里,对吧?好,找到这个列表,我们来给他绑定点击事件。找到这里啊,那这个列表是在前面生成的啊,在这里生成的Li,那我们给Li绑定一个click事件啊,一个on click。我们来给一个啊事件的一个名字,函数的名字就是to user啊向哪个用户去发送,然后既然要向哪个用户去发送消息,这里我们需要获取到用户一些信息,对吧?那首先得拿到这个用户的昵称啊,我们好显示就是向谁去发送啊,然后还要拿到用户的这个ID,因为在服务端我们如果要向某一个客户端去通信的话,需要借助于啊这个ID才可以啊。
01:15
需要借助于这个ser的ID才可以啊好,所以呢,这里呢,我们把这个加个单引号,用户的昵称是谁,用户的昵称是这个爱里面的啊,这个item里面的。Make name对吧?好来一个逗号,这个传参的时候,你一定要不要不要小少写东西啊,因为它是字符串,所以你要用单引号包起来,清楚吧,那外面是双引号不会有影响啊,就是然后外面最外面是这个啊模板字符串啊,所以我这里我们可以用dota直接去拿这个对象里面那些数据啊,直接是在里面写表达式item点。ID啊,那这个ID呢,是我们之前在服务端去加入用户的时候,哎,把用户存储用户信息的时候,哎给他把so克的ID给存进来了,清楚吧,这也是为什么我哎之前我们在写这个存储用户信的时候,给大家说过,我们提前给用户一个ID,用这个ID啊在某些情况下很有用,哎不管我们去筛选用户啊,还是我们像向指定的用户去发送消息,都要借助于这个SOID的,清楚吧,好。
02:17
那接下来呢,我们先验证一下这个两个参数能不能拿到啊,那我们来定一个to user的一个方法,在这就在这定义吧啊。Function to user这里写一下啊,点击。用户进行私聊。那接触两个参数对吧,一个是这个呃,Nina。一个是这个ID,好,我们先来打印一下这两个参数,看能不能拿到nickname这样log,然后再打印一下这个ID。好。
03:00
在这里啊,刷新一下。随便输入个三三。那我们就点击它。哎,是不是拿到了昵称是33ID是他对不对啊,那拿到了之后呢。这时候。我们就可以,哎,让这个信息啊,显示到哪里呢?显示到这里面啊,我们把这个呃,昵称给它显示到这里面。来写一下。Document第二,Get element by ID,看一下输入框的ID是什么。是。啊,这个input。这value啊,因为它是一个输入框嘛,所以我们使用这个value来进行设置啊,使用模板字符串,然后嗯,写一个私聊吧。加一个名字啊,就是给谁私聊啊,私聊私聊这个人。啊,然后还可以再加上一个冒号空格。
04:04
这时候我们再来看一下啊,刷新一下。来点击诶,可以看到有一个私聊谁孟浩对谁对吧,那后面我们再继续输入这个消息就可以了,对不对啊,但是现在我们来想一个问题啊,这个用户是不是我自己对不对,我能和自己私聊吗?啊,应该是不能的,那所以我们得加一个判断,就是不能和自己进行私聊,好吧,那我怎么知道是自己呢?我们可以通过什么区分啊,大家可以想到了,之前我们在加入这个。聊天室的时候是不是存储了用户信息,用户里信息里面是不是有niname,是不是可以用过,通过这个niname来区分是不是同一用户,对吧?啊,当然也可以,除非你Nina是唯一的,如果你那不是唯一的,别人叫小明,你也叫小明,是不是出现问题了,那我们唯一可以靠谱的,呃,能唯一标识用户的可还可以通过什么,通过这个ID对不对?对吧,但是这个ID呢,是服务端反馈给我们的ID啊,服务端反馈反馈给我们的ID,那么我们怎么知道当前这个用户啊,我们当前的这个客户端的这个ID呢?诶我们来想一想,我们这里有一个什么,是不是有。
05:12
对不对啊,So它有什么,So是不是有ID,你看我们在服务端我们就能通过so.id拿到当前这个客户端的啊连接的这个ID,那前端就是说客户端这里是不是也可以拿到。啊,前后端他俩的这个API是一致的啊,所以呢,我们来做一个验证啊。再来写一个o log,看一下这个so.id是不是和我们传输过来的这个一样啊,保存来刷新。输入一个随便输一个名字啊好,接下来我来点击。这个下面这个是我函数传过来的,就是服务端返回给我的这个列表,对吧,我点击这个事件传过来的ID,而这个是我直接输出的,从我当前客户端的里面去输出的。看到了吧,所以我们只需要判断什么判断这两个ID如果一致,就不让他死了。
06:00
来,我们做一个判断啊,If。ID等等于socket.id哎,我们给他弹一个消息啊,我封装了一个error方法。然后这边显示一个就说啊,不能和自己私聊。好,最后不要忘了return啊,Return掉。来保存,再来验证一下啊,我们写一个,我们给大家做一个看一看效果。现在来点,是不是不能和自己私聊?对吧,因为他的ID你知道吗?啊,这个是服务端返回的so的ID,那这是我们自己在客户端拿到的这个SOID啊,那。不能和自己私聊啊。那接下来开始处理我们下一步逻辑,那这个呢,只是一个GS的一个事件啊,就是为了让什么呢?让这个啊内容啊,我们私聊的谁显示到这里面啊,然后接下来。我们就开始,呃,给大家做个演示吧。
07:00
这里啊,我们有两个用户才好演示嘛,来加进来一个,再来加进来一个啊接下来呢,啊,这个是自己不能私聊,当我私聊别人的时候呢,那接下来我就要输入消息去发送给。发送出去对吧,好,但是我如果直接这么去发送消息的话,是不是还是广播给所有用户了,好,那为了作为验证。来,我在这里再来一个,来一个它好。现在我私聊的谁,是不是这个?123啊,123这个对吧,第一个这个,那如果我去发送消息,按说应该是他自己收到这个消息才对,但是别人也收到了,那说明我们的这个代码啊,还还得改对不对啊,那肯定得改,那虽然我们这个GS是处理完了,但是我们在发送消息的时候,我们来找一找代码在这啊发送消息的时候。是不是还是直接把这个消息给啊,发送给这个服务端的这里了,对吧,好,那在这个里面呢。注意它啊,在这个里面呢。
08:01
找到接收消息这里他是不是还是广播给除自己以外的一个用户了。对吧。啊,那说明我们得对他进行一个更改,不能广播给出自己用户,如果就是说我们是进行了私聊,应该广播给那个指定的那个用户。我们怎么知道啊,指定给了谁,是不是我们要把指定的那个用户那个SOID给传过来对不对?来看我们强调GS。找到哎,这里这里我们现在只传了消息,那我们是不是还要把一个这个呃,ID给传过来,对不对,但是ID等于谁。想一想我们sock的ID就是在私聊的时候,在哪个地方去拿到了别人的这个骚的ID啊,这里先问好,先放着啊,是不是在上面我们点击某个用户的时候啊,点击你看用户进行私聊,哎,是不是在这里我们拿到了别人的这个SID是传过来的函数传过来的,对吧?啊,那怎么这个ID怎么让下面那个方法用呢?哎,我们就是说还是简单的写吧,我们借助一个全局变量吧,好吧。
09:02
好create ID啊,一个私聊的ID,一开始呢,等于这个。啊空啊空字符串没有的啊,一旦你传过来了之后,那我就让你这个ID等于它好吧,这样的话,这个全局的这个变量就有了这个值,哎,在下面呢,我们就可以把这个值发送消息的时候。给传输给服务器对不对?好,如果没有点私聊,那它是一个空对不对,对吧,如果点了这个私聊,那就是具体的一个私聊的这个ID,好,那我们在服务器端就能收到这个ID,我们在对这个ID做一个判断是不是就可以了啊来我们在这里做一个判断,就说这个date里面啊,If date.id啊。等等一空啊,就说是啊,不是私聊,那不是私聊,我还是广播给自己以外的一个客户端,对吧,那如果是私聊的情况下。在这里写一下啊,这个是不是私聊。
10:03
那否则的情况下就是有SOID啊,是私聊的情况,那如果是私聊的情况,是不是只给。指定的这个啊,Socket。客户端嘛,哎,我们不说人了,我就说客户端啊,发送消息是这样的吧,那么怎么给这个指定的这个骚的发送消息呢?指定的so客户端发送消息,那怎么给这个指定的客户端发送消息呢。好,我们看一看上面我们所有能用到的这个啊,发送消息的方法啊,第一个是向所有的啊,这个呢,是像建立了该链接的客户端去发送这个广播,那这个呢,是向除了自己以外的所有客户端发送广播,诶显然没有符合我们的这个方法。
11:00
对不对啊,但这时候我们再来看看第二个,既然我们调用这个socket,它就能给这个socket这个客户端发消息,那么我如果调用了指定ID的这个socket,是不是就能给指定的这个人去发送消息。是不是这样的,好,那么我们怎么能通过ID去拿到对应的这个so呢?哎,这时候我们再来引入一个东西啊。叫什么呢?有一个。这个东西啊,IO啊叫sok so。点so啊这个。啊,加S啊。那就是IO这个对象里面的啊,Soet.soet。它是什么呢?它是存储了所有的已连接的对象。已连接的对象啊,是一个这个map集合啊,也就是说只要有一个客户端连接了,我就把这个客户端给存到这里面,那只要有一个客户端链接,我就存到这里面。
12:08
对不对。啊,那么我们如果想要拿到指定的,是不是通过这个ID,我们就可以拿到指定的这个客户端。是这样的吗?好,我们来打印一下,看一下对socket,哎,所以我讲东西是用到哪个给大家引出哪个,不是说一开始把所有的概念都给大家抛出来啊,这样大家也不太好记。点sos.log啊。来保存。好,可以看到大家已经在这里,这里已经有输出了,对吧,所有的一个客户端是不是来我们看一看它的这个类型,这是不是一个map map。对吧,你看这里是SOID啊,它的K是这个SOID,然后它的value就是一个so客户端,清楚了吧,也就是说所有的这个客户端连接都给存到了这个啊,这个map里面。啊,而且它的K就是ID。
13:00
啊,那它对应的值就是一个soet对象,那这个对象和我们这个对象是一样的,我们想要给当前的链接发消,发消息就是使用当前的这个soet加里面的,那么我如果想要给指定的一个客户端发消息,是不是我只要拿到这个指定的烧对象就可以了。啊,所以这里我们再来总结一下啊。呃,这里总结一个什么呢,我们。呃,写这个so啊。OG。嗯,就是这个。骚的对象啊。点啊可以给指定的KT。啊,对象啊客户端嘛。发送广播啊。
14:00
明白了吧,啊,那还是,哎,刚才我说的,我们既然通过它能给这个已连接的客户端发广播,就当前连接的,那么我们就能通过这个骚客对象去给指定的这个打广播,啊,那这个对象怎么来呢?就可以从这个io.s里面去获取,因为它是一个集合,从集合里面取数据非常方便的,我们使用get方法就可以了。是不是这样的好?那我们这里呢,就把它先注释掉啊。嗯。来这里再给大家写完整啊,So sot o g CT可以从这个集合里面啊。写到这儿吧。好,这个啊so啊的一个对象可以从这个集合里面获取。好,那接下来去完成我们的私聊的功能,那我们知道这个里面存储了所有的啊骚的对象。然后我们再进行广播的时候,是不是要先拿到指定的这个客户端。
15:07
哎,To so吧,等于谁,等于所有的这个so集合里面,我们使用get方法来取指定的这个K,它的K是谁?是不是用的ID存档ID在哪,ID是不是我们data里面由客户端发过来了,对不对,这样就拿到了指定的这个soet,那如果要给他发送消息就使用啊,To soet。点塔。来触发这个,呃,客户端的这个消息就可以了啊,那触发他的什么方法呢?啊,还是触发他的。Get message方法就可以啊啊跟这个是一样的啊,跟这个是一样的。啊,同时要把这个date给他,因为这个方法就负责显示消息啊,以及展示这个用户走向,而用户的数据以及消息都在这个data里面的。那我们这里是用的啊two socket这个变量,那为了保持统一,我们把前面都改改了啊two socket这。
16:09
把这里往前缩进缩进啊。可以向哎指定的吐槽的客户端去发送这个消息好。接下来我们来做一个测试吧。哎,例子写完就开始测试123,哎,因为测试私聊呢,我就在准备三个啊,昵称我就用一。二。三。啊,三个人。接着。那我这个是一啊,这个客户端是一一,我给谁私聊呢?给这个三私聊吧,嗯,333你好。发送好,首先看二二肯定是收不到的,对吧,那我们来看三三是能收到的。看到了吧,这就私聊向指定的一个客户端去发送消息,那通过谁通过so的ID,我们可以把这个指定的客户端给筛选出来。哎,私聊我们就行了,是不是比较简单,那通过这个写对私聊,我们又引出了一个发送消息的一个方法,哎,指定的客户端,哎使用他的it去触发指定的客户端监听的这个事件啊,至于客户端为什么我们不处理呢?我们还是呃使用统一的这个呃接收消息的方法就可以,因为。
17:15
只要客户端收到消息,无非就是把消息和用户的头像名称显示出来,哎,所以这个方法是统一的啊,是一样的,这个不用我们做调整啊,需要调整就是我们在服务端需要做一个判断,就是有没有这个私聊的ID,如果有啊,我们就只给这个私聊的这个客户端去发消息,如果没有的话,就广播给自己以外的啊,需要对这个做ID,那这个SOID我们是怎么处理的呢?哎,我们也是取了一个巧,在我们选择好私聊对象之后,我们把这个骚ID给它定义成了一个全局的一个变量,对吧?那如果我们点击谁的私聊,我们给这个变量进行赋值啊,这时候这个变量就有值了。是不是好?但是呃还有一个情况是这个全局变量它现在有值了,对吧,那一旦我们在呃发送完这个消息之后,我们要把这个全局变量给制空,要不然这个。
18:04
就是一直是私聊状态,你就回不到这个公聊了啊,回不到这个公共的聊天了,所以说啊。找到这里啊,我们在发送给发消息给服务端以后啊。啊,甚至说是显示完自己的消息以后,我们放在最后吧。星空。私聊对象的啊,私聊对象哎,就是让这个ID等于空,一定要清空啊,你要不清空的话,那全局的这个ID就一直有值,一直有值,那你永远就是私聊状态了,明白吧,一定要清空啊。好,那这个就是我们关于这个啊,私聊的一个,呃,写法已经写完了。那这小节我们先到这里。
我来说两句