自贡建设监督质量网站,信宜做网站设置,无锡市新吴区建设环保局网站,定制做网站技术实时性
1.线程池多线程#xff0c;把消息同步给其他端和对方用户#xff0c;其中数据持久化往往是最浪费时间的操作#xff0c;可以使用mq异步存储#xff0c;因为其他业务不需要拿着整条数据#xff0c;只需要这条数据的id进行操作。
2。消息校验前置#xff0c;放在t…实时性
1.线程池多线程把消息同步给其他端和对方用户其中数据持久化往往是最浪费时间的操作可以使用mq异步存储因为其他业务不需要拿着整条数据只需要这条数据的id进行操作。
2。消息校验前置放在tcp层netty服务中
可靠性 tcp协议只能保证数据在传输过程中不丢失但不能保证到某一端不会丢失比如传输过程中接收方断网数据就无法发送到接收方 。
可靠性可以通过消息重发来保证消息一定送到了对方手中。可以通过双重ack确认机制来实现
A向im服务端发送数据服务端收到就返回一个ackA收到这个ack就停止重发否则就再次尝试重发。当然重发需要设计上限次数的。
然后服务端接到A的数据再发送给BB接到之后告诉服务端返回一个接受到的ack。服务端把收到的再传回给A此时A确定了此次传输是成功的。中间任何环节出问题A就执行重发就ok了。
如果B不在线服务端是可以感知到的服务端可以代替B向A回复停止重发指令。
有序性
因为我们使用多线程保证了消息的实时性那么就会导致消息有乱序的风险。
解决方案
使用redis的incr命令实现原子性的递增序列号但是过度依赖redis可能会因为redis的崩溃而造成系统失效
幂等性
再im服务端存储每次发过来的消息id设置过期时间重复发送的消息id将不再进行持久化但仍会给另一个客户端发送消息。这样就会导致另一个客户端由于网络问题如果没有及时返回ack确认那么他确实会收到2条相同的消息但是在去重是完全可以处理的。
qq发消息失败会有红色感叹号当再次点击重发时是把它当作一条新的消息id发送的而不是之前的消息id。
消息已读功能
在写扩散中每个人对自己的每条消息都可以直接获取已读只不过是个字段罢了。
在读扩散中以群聊为例可以在群成员表中加入一个字段该字段表示改成员读到的最后一条消息序列保证有序性的那个递增序列在这条消息之前的就表示读过了
离线消息存储
IM即时通讯系统中的离线消息是指在目标用户不在线或者不可达时发送方发送的消息无法直接传递给目标用户而是被服务器暂时存储起来等到目标用户上线或者可达时再进行投递。
离线消息的存在是为了保证消息的可靠性和完整性。当发送方发送消息时如果目标用户在线消息可以直接传递给目标用户但如果目标用户不在线服务器会将该消息存储在消息队列或者数据库中等到目标用户上线后服务器会将离线消息投递给目标用户。
离线消息通常具有以下特点
持久化存储离线消息通常被存储在服务器的数据库或者消息队列中确保消息的持久性即使服务器重启或者断电消息也不会丢失。时效性离线消息通常会设置一个过期时间在一定时间范围内等待目标用户上线过期后会被清理或者丢弃。投递策略服务器会在目标用户上线后根据一定的投递策略如先进先出、按时间戳等将离线消息按顺序投递给目标用户。通知机制当目标用户上线后服务器可能会发送通知给目标用户告知其有离线消息待接收。
这里的存储使用redis每人只存1000条超过就淘汰最早的使用zset存储使用消息的递增序列号作为排序标准zset支持查询范围内指定数量的元素SMEMBERS命令。
即使你错过了离线消息的通知和消息盒子你仍然可以通过滚动查看聊天记录找到之前的离线消息。
登录之后的数据同步历史记录的拉取
不可能说每次登录都把所有记录都删了重新拉取一遍的所以这里采用增量拉取。
需要拉取的东西有会话好友列表好友申请为每个需要拉取的数据记录下他的递增序列号每次只拉取大于记录里最大的序列号。
客户端可以用数据库sqllite
在线状态设计
正常情况下你的上线和下线等状态应该通知给你的所有好友和你在的所有群里的所有成员这将是非常恐怖的数据量。
改进1只推给在线用户
改进2
按需拉取在按需拉取的策略下IM 系统不会主动向所有好友和群成员发送上线和下线等状态通知。相反当其他用户需要获取某个用户的状态时他们可以向服务器发送请求然后服务器根据请求返回相应的状态信息。这种方式可以避免将状态通知广播给所有人只有真正需要获取状态信息的用户才会发起请求减少了不必要的数据传输和处理。临时订阅临时订阅是指用户可以临时订阅某个好友或群组的状态更新通知。当用户订阅了某个用户或群组后只有在被订阅对象的状态发生变化时系统才会向订阅者发送通知。这样可以避免向所有好友和群成员广播状态更新只有被订阅的对象状态发生变化时才会发送通知给订阅者。这种方式可以根据用户的实际需求选择性地接收特定用户或群组的状态更新通知减少了不必要的通知量。
陌生人发消息限制 计数限制为每个用户设置一个计数器记录他们发送给陌生人的消息数量。当陌生人发送消息时系统会检查计数器的值。如果计数器小于等于三允许发送消息并将计数器加一如果计数器大于三拒绝发送消息。 时间限制除了计数限制可以设置一个时间限制例如每小时或每天只允许陌生人发送三条消息。系统会记录陌生人发送消息的时间并在规定的时间段内检查发送数量。如果超过限制拒绝发送消息。