前言:这篇主要解决上个小章节遗留的问题,第一个:当我们返回的时候它的最新消息应该是能实时更新的,同时未读消息数也应该是能默认更新的。第二个:根据是否在同一个‘房间’去判断插入数据库的消息应该是已读的还是未读的。
进行编写代码之前我们照例进行思考,第一个问题中其实在chat页面应该只有一个场景,当我们引入了vuex进行全局的状态管理的时候,我们只需要在消息更新、发送的时候告诉两个人,一个是对方,一个是自己,这两个人自己按需进行更新。而不是重新去渲染列表。
如果这时候你觉得我们可以在返回的页面前在发送可以进行优化,这里我可以明确的说明不可以。因为这里其实还包含了对方处于index页面实时的接收你发过来的消息的场景,所以必不可少的,我们只能每一条消息发出去后都得处理这个状态。
初步思路有了后,我们尝试下编写代码。
问题
1.监听消息的改变
上面的代码用意很明显,我们不仅希望自己发送之后返回index页面可以实时的更新,而对方假如处于index页面接收消息的场景,他也应该是可以实时的接收到的才对,所以同样的,我们也需要给对方发送一个消息改变的事件。其中传的参数为什么要这么写?我们必不可少的需要http请求一次用于向服务器端查询tips未读消息数,即使我们可以在socket连接后直接获得最新的消息。curIndex用于我们去进行按需更新。
2.接收消息的改变
首先在我们发送消息的函数里发送消息被改变了的事件,curIndex在onload生命周期里获取。接着修改我们的渲染方式,将他修改成vuex的渲染方式,这一点是必须的。因为这里的情况同样是有两种,其中的一种是你在chat页面发送消息,修改了我们的渲染值是不会生效的,相当于说你在chat组件里修改index组件的值是不被允许的。
介绍dispatch
看不懂是吧?没关系,我也看不懂。但这个是个不错的东西,反正我现在使用不是为了他的异步操作只是觉得这样方便管理有关提交的代码。
onload生命周期里加上 await this.$store.dispatch(‘moduleIndex/saveUserAndFriend’,[msgImgAndName,userInfo,this.msgList]);
好,这样子之后我们的渲染方式就是从vuex中读取渲染的消息列表了。接着就到接收消息的变更的核心了。
我猜测这里能让你产生疑惑的应该有两点
1:就是那几行交换的代码,同样是场景所导致的,假如你是自己发出去更新自己的消息,那你传过来的userId就应该是自己,friendId就是对方,这是没有问题的,但假如是对方发过来的消息,那此时传过来的userId就不是你自己的Id,你在观察我们写的接口,作为接收方的应该是自己的id才能准确的查找到未读消息数,这个是丝毫不会影响到消息的变更的。
2:使用Vue.set() 将这个我们从数据库查出来的数据放入vue中,让vue进行数据绑定,自动更新。这里若是直接就使用这个数据觉得可以进行视图渲染是错误的。这个数据是未被vue进行初始化数据处理的。
效果
测试
经过随机测试后 ,发现一个BUG,这个BUG是由于我们先前的代码造成的,好在的是他比较明显。主要是由于我们需要通知的用户是依赖于名字这个信息的,而实际上,当我们改变了首页的信息渲染时,存储在vuex里的imgAndName数据我们并没有给他更新,导致当改变了首页的渲染顺序后在发送信息的方向上出了问题。而这段逻辑已经出现了两次了,所以把之前我们在onload逻辑中的相关代码封装起来进行使用。但是得注意 这种带有相关依赖得函数得使用必须慎重。
如上写法可能会产生得不到预期结果的错误。原因很简单,我们收集的这个数据是依赖于新的msgList的。但我亲测了一下,发现vuex的状态被提交后的数据更新似乎与我预想中的有些区别,这里无论顺序如何更改它都是能正常运行的,因为我也没看过vuex的有关源码,暂且只是猜测在数据更新我不太理解在什么时候。由于还在苦逼的写项目,就不去深究了。
现在就以为结束了?并没有,它又出BUG了,别慌,慢慢来吗。随着你胡乱的测试,你又会发现你在h5这边输入,消息的显示是正常的,但当你查看模拟器的时候你就会头晕。这里就懒得截图了,因为过年这博客断断续续地写。
产生这个问题的原因也挺直观,我们传了个curIndex不是?同样是场景问题,你的curIndex不等于对方的curIndex啊,所以呢。不管怎样,这个curIndex还是得计算出来。最终消息接收的完整代码如下
2.判断双方用户的连接状态
使用场景:参照QQ和微信,假如你跟聊天的对方 处在同一个聊天页面,彼此的消息就应该是已读的。这就代表我们在这个状态的时候插入的数据库的msg_status应该是1,那如何界定这个状态呢?
后端
下面详细的说明下主要实现思路(也许有我没测试到的BUG,比如多人):首先创建一个oneToOneJoin对象用于保存当前的用户是否是可以被连接的状态,对象存在该用户,与对方用户就表示可以被连接,同时发送msg_status的插入状态应该为1;当我们退出的时候,我们把该用户添加回oneToOneJoin对象中,表示当前用户又可连接了。所以这里又得判断,因为我们的前提条件是,对方与我方都在同一个‘房间’才进行删除用户操作,所以假设socketList里存在该用户,而且不存在在oneToOneJoin对象中,自己处于可连接状态,这时候也是双方都在连接的。别的所有的都是false,不再赘述。
前端
发送消息里对插入数据库的默认值修改,根据this.friendOnLine 去判断当前插入的是0 或者是1
本来还得截上测试的图片的,太监了,不写了。自己去学别的了。