聊天室快速访问
继上次完成聊天室的历史记录功能后,我又想着实现聊天记录的已读未读功能。(轻喷。。)

开始之前

首先我看了抖音和钉钉这两款应用的消息已读未读功能的呈现效果。首先是抖音,在聊天界面,给好友发送完消息后,消息界面的最右下角有一个“已发送”标记,这时候是属于对方未读,如果对方上线并别点开了和你的聊天界面,你和他的聊天界面上,那个“已发送”就变成了“已读”,所以抖音并不会每一条消息上面都显示“已读”或者“未读”。而钉钉,由于其专注于办公,这个已读未读功能就“变态”多了,每一条发出去的消息都会显示对方是已读还是未读。

学谁?

当然了,我只能通过抖音或者钉钉在功能上呈现出来的效果来结合自己掌握的知识来推断他们大概的实现过程,真正的实现可比想的复杂多了,所以我也是照葫芦画瓢,做一个能用的精简版已读未读功能。既然是照葫芦画瓢,那就学钉钉吧,做一个“变态版”,每一条消息都显示“已读”或者“未读”。

思考

A和B聊天,如果A发送一条消息给B,怎么知道B已读呢?当然是B收到消息后,发送一个“已读回执”,A接收到已读回执后,更新自己的UI,把“未读”改为“已读”。

啊!挺简单啊。。。

可,,可是,如果B不在线,或者B在线,但是没有打开和A的聊天界面,那B不也是未读A的消息吗?如果B不在线,A发完消息后下线了,这时B上线了,查看消息后,发送已读回执给A,可是A已经下线了啊,怎么保持已读状态?此外,消息的已读和未读状态要保持的话,是该给消息添加一个属性,标识已读未读吗?如果添加属性,意味着我以前的代码也得改?比如一些操作数据库的代码和逻辑。

啊!

我怎么做

首先,并不需要给消息添加一个已读未读标识,只记录一个B最近已读A消息的时间即可。这样怎么就行呢?

1.设计“已读回执”结构

已读回执很简单,就是两个id和一个时间戳,id分别是读消息的A用户id、发消息的B用户id,时间戳是A最近一次读取B的消息的时间。这个已读回执是存到Redis中去的,最终会通过定时任务在凌晨三点持久化到数据库。例如id为3的用户发送已读回执给id为5的用户,则Redis中保存一个Value(key:‘3-4-readTime’, ×××)

2.“已读回执”怎么用

给一个场景A和B两个用户,进行对话。我们来分情况讨论一下吧:

  • A上线,A点击好友列表中的好友B,这个动作即会触发发送一个已读回执给B(即使没有未读消息),同时存在Redis中。

    • B在线,B收到回执会把和A的聊天中的A未读的消息更改为已读
    • B不在线,B不能即时收到这个回执。等到B下次上线的时候,首先会去Redis中获取每个好友给自己的回执缓存(如果缓存没有则取数据库中获取,同时更新到缓存),这里能获取到好友A的回执,将回执里面的时间和要渲染到界面上的B发的每条消息的时间去比较,如果回执中的时间大于消息时间,则该消息标记为“已读”,否则标记为“未读”。
  • A上线,点击列表中的好友B,执行完上面的过程,A发消息给B,A的界面显示这条消息,并显示此消息未读
    • B在线:

      • B这时开着的是和A的聊天界面。B收到A的消息,立刻显示了出来,随即发送一条已读回执给A,同时更新Redis。如果A在线,则收到这条回执,把界面上的所有未读消息更改为“已读”。如果A不在线了,下次上线也可以通过缓存的回执或者持久化到数据库中的回执来渲染界面,显示“已读”。
      • B这时开着的不是和A的聊天界面,则不发送回执给A,A界面继续显示“未读”。当B打开和A的聊天界面,才发送回执,同时更新Redis。
    • B不在线:A界面这条消息继续显示“未读”。只有在下次B上线的时候,B点开和A的聊天界面,才会给A发送已读回执。A在线则获取实时的回执,如果不在线则下次上线的时候获取回执渲染界面。

Redis宕机了怎么办

和历史记录的实现一样,对于我这个单服务器系统,那就只能直接保存到数据库了。另外Redis持久化策略可以在下次启动的时候恢复数据。

遇到的坑

这个思路是没什么复杂的,但是实施起来就有很多小细节了。在一个坑上面花了很多时间。就是js获取的时间戳,在java中转成Timestamp的时候出错,导致我在调试的时候一旦发送已读回执,接收已读回执的那个客户端就会断连。最后发现是Timestemp这个东东,不能用强转字符串来得到,大意了,需要通过Timestamp.valueOf(×××)来把一个字符串转为时间戳,而且这个传入的字符串需要以yyyy-MM-dd HH:mm:ss的格式来的。当时写太快了,就用(Timestamp)强制转换。。。

截图:

Web聊天室消息[已读未读]的实现相关推荐

  1. vue+websocket+nodejs实现聊天室 - 消息已读未读

    前言 上一篇讲了聊天室增加一对一单聊,这次讲如何新增已读未读状态. 大概思路: 服务器返回消息列表,增加参数status为1,单聊和群聊通过过滤状态区分对应未读数量,当前聊天,直接在currentMe ...

  2. IM群聊消息的已读未读功能在存储空间方面的实现思路探讨

    1.引言 IM系统中,特别是在企业应用场景下,消息的已读未读状态是一个强需求. 以阿里的钉钉为例,钉钉的产品定位是用于商务交流,其"强制已读回执"功能,让职场人无法再"假 ...

  3. 踩坑记录:消息推送已读未读

    一.需求 最近工作中遇到了一个坑,在次记录一下. 社区管理员在后台发布一条社区公告,手机端该社区下的所有居民都可以收到这条公告,并且消息有已读未读状态. 二.分析 这个需求看起来很简单,无非就是后台发 ...

  4. 面试官:群聊消息的已读未读功能,你来设计一个?

    欢迎关注方志朋的博客,回复"666"获面试宝典 一朋友和我讨论他前段时间面试某大公司的一题目 : 企业IM比如企业微信.钉钉里面的群消息的有个已读未读的功能,发送者刚发出消息时,当 ...

  5. 群聊消息“已读”/“未读” 功能解决方案!

    一朋友和我讨论他前段时间面试某大公司的一题目: 企业IM比如企业微信.钉钉里面的群消息的有个已读未读的功能,发送者刚发出消息时,当前群里其他群成员都是未读状态,陆陆续续有人看了这个消息,这时候消息的详 ...

  6. mysql消息已读未读_Redis实现信息已读未读状态提示

    本文为大家分享了Redis实现信息已读未读状态提示的关键代码,希望可以给大家一些启发,具体内容如下 前提: 假如现在有2个模块需要提示消息:只要存在用户在上个时间点之后没有看过的信息就提示用户有新的信 ...

  7. 面试题:群聊消息的已读未读设计

    点击上方"Java之间",选择"置顶或者星标" 你关注的就是我关心的! 作者:小猿学习笔记 一朋友和我讨论他前段时间面试某大公司的一题目 : 企业IM比如企业微 ...

  8. Android已读未读功能,android – 将SMS消息标记为已读/未读或删除在KitKat中不起作用的消息...

    我一直在研究短信应用程序.直到昨天,当我将Nexus 4更新为 Android 4.4,KitKat时,一切顺利.诸如将SMS标记为已读/未读以及删除线程中的所有消息等功能已停止工作.为什么会这样?它 ...

  9. android读信息会话,在融云 IMkit 会话界面基础上添加消息已读未读.

    在融云 IMkit 会话界面基础上添加消息已读未读. 使用过融云的同学们可能知道. 融云 IMkit 的会话界面, 发送玩消息后, 如果对方已读, 发送端则会显示小对号的图片. 但是更具需求要把小对号 ...

最新文章

  1. SaltStack WEB UI Halite初体验
  2. html5 java 图片上传_java实现图片上传至服务器并显示,如何做?希望要具体的代码实现...
  3. 0924html小测答案
  4. Java讲课笔记28:Path接口和Files工具类
  5. socket中使用心跳来检测连接是否断开[ZT]
  6. 阿里巴巴笔试题目(接示本质的解法)
  7. 手动部署ceph octopus集群
  8. SQL server连接数据库
  9. php连接sql server
  10. C语言 PTA 新年倒计时
  11. Linux磁盘空间管理利器--ncdu(为你的 系统瘦身)
  12. 【网络安全】学习笔记 --02 安全通信协议
  13. [paper]Defense against Adversarial Attacks Using High-Level Representation Guided Denoiser
  14. 不用linux转录组数据分析,RNA-seq转录组数据分析
  15. 命令与征服3 凯恩之怒
  16. 20145212罗天晨 注入shellcode实验及Retuen-to-libc实验
  17. null不可以toString
  18. 苏宁大数据部门前端面试
  19. 数字图像处理第九章----形态学图像处理
  20. MIPCMS模板开发之导航栏隐藏某项导航

热门文章

  1. LTE学习理解系列——PSS和SSS序列定点化
  2. file Android close,file close是什么意思
  3. python数据获取就业方向_基于Python的就业岗位数据获取与预处理
  4. 小白如何从零开始设计并开发一个微信小程序?
  5. 【运营】Google search console
  6. ArcGIS arcpy代码工具——将要素属性表字段及要素截图插入word模板
  7. html中hover无法触发,CSS hover失效的原因总结
  8. Laravel 任务调度(计划任务,定时任务)
  9. Python小顶堆的实现
  10. 未保存的PPT,Word等文件,关机后,如何恢复?