前言
https://github.com/hua1995116/webchat
这个项目本来是我学生时代为了找工作的一个练手项目,但是没想到受到了很多的关注,star也快要破K了,这也激励着我不断去完善他,一方面是得对得起关注学习的人,另一方面也是想让自己能过通过慢慢完善一个项目来让自己提高。
今天给大家带来的是基于Websocket+Node+Redis未读消息功能,可能更加偏向于实战方向,需要对Websocket和Node有一些了解,当然不了解也可以看看效果,效果链接( https://www.qiufengh.com/ )说不定会激起你学习的动力~
下面我通过自己思考的方式来进行讲解,代码可能讲的不多,但是核心逻辑都进行了讲解,上面也有github地址,有兴趣的可以进行详细地查看。自己的idea或多或少会有一些不成熟,但是我还是厚着脸皮出来抛头露脸,如果有什么建议还请大家多多提出,能让我更加完善这个作品。
设计
首先对于消息未读,大家都很熟悉,就是各种聊天的时候,出现的红点点,且是强迫症者必须清理的一个小点点,如?所示。我会带大家实现一个这样的功能。
由于一对一的方式更加简单,我现在只考虑多对多的情况,也就是在一个房间(也可以称为群组,后面都以房间称呼)中的未读消息,那么设计这样的一个功能,首相我将它分成了3种用户。
离线用户
在线用户
在线用户且进入群组的用户
离线用户
这种场景就相当于我们退出微信,但是别人在房间里发的消息,当我们再次打开的时候依然能够看到房间增长的未读消息。
在线用户
这种场景就是相当我们停留在聊天列表页面,当他人在房间中发送消息,我们能够实时的看到未读消息的条数在增长。
场景示例。
在线用户且在房间的用户
这种场景其实就比较普通了,当别人发送新的消息,我们就能实时看到,此时是不需要标记未读消息的。
场景示例。
流程图
主要流程可以简化为三个部分,分别为用户,推送功能,消息队列。
用户可以是消息提供者也可以是消息接受者。以下就是这个过程。
当然在这个过程中涉及比较复杂的消息的存储,如何推送,获取,同步等问题,下面就是对这个过程进行详细的描述
图上的流程解释
A. 存储在Node缓存中的房间用户列表(此处信息也可以存在Redis中)
B. 存储在Redis中的未读消息列表
C. 存储在MongoDB中的未读消息列表
用户1进入首页。
用户1进入房间,重置用户在房间1的未读消息,触发更新模块去更新B未读消息列表。
用户1向向房间B中发送了一条消息。
后端需要去获取房间用户列表,判断用户是否在房间?
是,因为在房间中的用户已经读取了最新消息,不需要进行计数。
否,若用户不在房间中,更新其的未读消息计数
从缓存中获取用户的消息进行分发。
用户2登录我们的项目,从离线用户变成了在线用户。
用户2登录时,触发查询模块,去获取其当前在各个房间未读消息情况。
查询模块去查询Redis中的未读消息,若Redis中没有数据,会继续向数据库中查询,若没有则返回0给用户。
Redis缓存将会每分钟和数据库同步一次,保证数据的持久化。