socket未读消息 如何设计_消息未读之点不完的小红点设计思路(Node+Websocket)

前言

https://github.com/hua1995116/webchat

这个项目本来是我学生时代为了找工作的一个练手项目,但是没想到受到了很多的关注,star也快要破K了,这也激励着我不断去完善他,一方面是得对得起关注学习的人,另一方面也是想让自己能过通过慢慢完善一个项目来让自己提高。

cc59ca7446578f8288046f79cfb36257.png

今天给大家带来的是基于Websocket+Node+Redis未读消息功能,可能更加偏向于实战方向,需要对Websocket和Node有一些了解,当然不了解也可以看看效果,效果链接( https://www.qiufengh.com/ )说不定会激起你学习的动力~

下面我通过自己思考的方式来进行讲解,代码可能讲的不多,但是核心逻辑都进行了讲解,上面也有github地址,有兴趣的可以进行详细地查看。自己的idea或多或少会有一些不成熟,但是我还是厚着脸皮出来抛头露脸,如果有什么建议还请大家多多提出,能让我更加完善这个作品。

设计

首先对于消息未读,大家都很熟悉,就是各种聊天的时候,出现的红点点,且是强迫症者必须清理的一个小点点,如?所示。我会带大家实现一个这样的功能。 415bb47b1868d06c492df23bc3bed3e3.png

由于一对一的方式更加简单,我现在只考虑多对多的情况,也就是在一个房间(也可以称为群组,后面都以房间称呼)中的未读消息,那么设计这样的一个功能,首相我将它分成了3种用户。

  • 离线用户

  • 在线用户

  • 在线用户且进入群组的用户

离线用户

这种场景就相当于我们退出微信,但是别人在房间里发的消息,当我们再次打开的时候依然能够看到房间增长的未读消息。

在线用户

这种场景就是相当我们停留在聊天列表页面,当他人在房间中发送消息,我们能够实时的看到未读消息的条数在增长。

场景示例。 630280a9d50bce615ae9f4f9601fdec0.png

在线用户且在房间的用户

这种场景其实就比较普通了,当别人发送新的消息,我们就能实时看到,此时是不需要标记未读消息的。

场景示例。 c266f2d75e561a7f11a7b29c5e746e64.png

流程图

主要流程可以简化为三个部分,分别为用户,推送功能,消息队列。

用户可以是消息提供者也可以是消息接受者。以下就是这个过程。 4215a11e085734f136c7e69ee3b3f246.png

当然在这个过程中涉及比较复杂的消息的存储,如何推送,获取,同步等问题,下面就是对这个过程进行详细的描述

6a80b908a4868bd32f3937d2bf708041.png

图上的流程解释

A. 存储在Node缓存中的房间用户列表(此处信息也可以存在Redis中)

B. 存储在Redis中的未读消息列表

C. 存储在MongoDB中的未读消息列表

  1. 用户1进入首页。

  2. 用户1进入房间,重置用户在房间1的未读消息,触发更新模块去更新B未读消息列表。

  3. 用户1向向房间B中发送了一条消息。

  4. 后端需要去获取房间用户列表,判断用户是否在房间?

  5. 是,因为在房间中的用户已经读取了最新消息,不需要进行计数。

  6. 否,若用户不在房间中,更新其的未读消息计数

  7. 从缓存中获取用户的消息进行分发。

  8. 用户2登录我们的项目,从离线用户变成了在线用户。

  9. 用户2登录时,触发查询模块,去获取其当前在各个房间未读消息情况。

  10. 查询模块去查询Redis中的未读消息,若Redis中没有数据,会继续向数据库中查询,若没有则返回0给用户。

  11. Redis缓存将会每分钟和数据库同步一次,保证数据的持久化。

环境

    • 0
      点赞
    • 4
      收藏
      觉得还不错? 一键收藏
    • 0
      评论
    要实现websocket监听消息数量和已,可以在后端维护一个消息状态的数据结构,并在前端通过websocket连接不断地获取最新的消息状态。 下面是一个简单的示例代码,假设你使用的是Node.js和Socket.IO: 后端代码: ```javascript const app = require('express')(); const http = require('http').createServer(app); const io = require('socket.io')(http); // 维护消息状态的数据结构 const messageStatus = { total: 0, unread: 0 }; io.on('connection', (socket) => { console.log('a user connected'); // 发送最新的消息状态给客户端 socket.emit('messageStatus', messageStatus); socket.on('disconnect', () => { console.log('user disconnected'); }); }); // 模拟新消息到来 setInterval(() => { messageStatus.total++; messageStatus.unread++; // 向所有客户端发送最新的消息状态 io.emit('messageStatus', messageStatus); }, 5000); http.listen(3000, () => { console.log('listening on *:3000'); }); ``` 前端代码: ```html <!DOCTYPE html> <html> <head> <title>WebSocket Example</title> <script src="https://cdn.socket.io/socket.io-3.0.1.min.js"></script> </head> <body> <div>总消息数: <span id="total"></span></div> <div>消息数: <span id="unread"></span></div> <script> const socket = io('http://localhost:3000'); socket.on('messageStatus', (messageStatus) => { document.querySelector('#total').textContent = messageStatus.total; document.querySelector('#unread').textContent = messageStatus.unread; }); </script> </body> </html> ``` 这段代码中,后端维护了一个`messageStatus`对象,其中包含了总消息数和消息数。每当有新消息到来时,`messageStatus`会被更新,并通过`io.emit('messageStatus', messageStatus)`向所有客户端发送最新的消息状态。 前端通过`socket.io`连接到后端,并监听`messageStatus`事件,一旦收到最新的消息状态,就更新页面上的总消息数和消息数。 这只是一个简单的示例,实际应用中,你可能需要根据具体业务需求对消息状态的数据结构进行调整,并在前端实现更复杂的逻辑。
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值