Server 请求 Redis 获取发送者 userid incr 得到新的 seqId,并落库消息
Server 将消息写入 MQ,交给 MQ 的消费者异步处理,MQ 保证服务端消息可靠性
Server 回复 clientA ACK 消息,携带接收消息中的 clientId 和前面发送者得到的最新 seqId
Server 中的 MQ 处理消息前,通过 Redis 获取收件人 userId 的 seqId,落库消息,并进行下行消息推送
Server 发送消息后创建消息计时器,丢入时间轮等待超时重发,或者收到 clientB ACK 后取消超时重发
群聊消息通过 seqId 保证:
单个客户端群聊中,看到的任一(任何一个)客户端消息顺序和其发送消息顺序一致(群聊中存在 ABC,A 看到 B 的消息肯定和 B 的发送顺序一致,A 看到 C 的消息肯定和 C 的发送顺序一致)
在多个客户端参与同一个群聊时,每个客户端所看到的来自任何一个客户端发送的消息以及消息发送的顺序都是一致的。但是,不同客户端所看到的消息顺序可能不同(群聊中存在 ABC,A 看到 B 的消息肯定和 B 的发送顺序一致,C 看到 B 的消息也肯定和 B 的发送顺序一致,但是 A 看到的整体消息可能和 C 看到的整体消息顺序不一致)
优化点:
使用会话层面的 id,能保证群聊绝对有序,但是需要再构建会话层,维护更多状态,不确定是否值得
换一种 id 生成的方式
3下行消息的可靠性
Server -> clientB:使用 seqId 保证:
Server 携带该用户最新 seqId 发送消息给 clientB
clientB 检查消息中的 seqId 是否等于自己本地存的 seqId+1,如果是则直接显示,回复 Server ACK 消息并更新本地 seqId