IM - 核心功能之消息收发和MQ设计

1. 概述

本文继续介绍IM系统核心功能之二,分别是

  • 消息收发
  • RabbitMQ设计

2. 消息收发流程

流程图

如下图,关于消息审计Auditor功能,遵从消息上行->消息审计->消息下行流程

  • 如果审计成功,则publish消息给receiver,走消息下行流程
  • 如果审计失败,则publish消息给sender,告知特定msgId的消息审计失败audit-fail,以及具体原因
    im-message-send-receive.png

那么,在客户端的消息发送状态变更如下:

  • 发送中,消息进入消息展示框,客户端执行send流程
  • 未读(发送成功),收到send-ack后,显示未读,或发送成功
  • 发送失败,超过3分钟没有收到send-ack,则显示发送失败,期间可以每分钟自动重发一次。失败后,支持手动重发(seq_id不变)
  • 审计失败,收到audit-fail后,显示审计失败,及失败原因
  • 已读,收到read-ack后,显示已读
im-message-status-in-client.png

代码实现

  • 消息上行
im-message-send.png
  • 消息下行
im-message-receive.png

3. RabbitMQ应用设计

单聊

user1@region1/desktopuser2@region1/desktop发送消息为例,介绍MQ消息流转流程

  • SM1收到PackageType=send的message,查询在线用户列表,补充receiver信息,从user2改成user2@region1/desktop,然后Publish RoutingKey=user.user1@region1/desktop.send到Exchange
  • Exchange会自动分发给RecorderAuditor两个服务
  • Auditor收到packageType=send的message,完成message审计工作
  • 如果审计成功,则Publish RoutingKey=user.user2@region1/desktop.receive到Exchange
  • 如果审计失败,则Publish RoutingKey=user.user1@region1/desktop.audit-fail到Exchange
  • 如果SM1收到RoutingKey=user.user1@region1/desktop.audit-fail的消息,则告知user1@region1/desktop
  • 如果SM3收到RoutingKey=user.user2@region1/desktop.receive的消息,则下行消息给user2@region1/desktop
  • 如果Broker收到RoutingKey=user.user2@region1/desktop.receive的消息,则判断user2@region1/desktop是否在其他Region,如果在,则下行消息给对应Region的Broker,否则,丢弃该消息

如果Broker收到其他Region的下行消息,则直接Publish RoutingKey=user.user2@region1/desktop.receive到Exchange,不再走Auditor

群聊

user1@region1/desktopgroup1发送消息为例,介绍MQ消息流转流程

  • SM1收到PackageType=send的message,如果receiver是群组,则直接Publish RoutingKey=user.user1@region1/desktop.send到Exchange
  • Exchange会自动分发给RecorderAuditor两个服务
  • Auditor收到packageType=send的message,完成message审计工作
  • 如果审计成功,则Publish RoutingKey=group.group1.receive到Exchange
  • 如果审计失败,则Publish RoutingKey=user.user1@region1/desktop.audit-fail到Exchange
  • 如果SM1收到RoutingKey=user.user1@region1/desktop.audit-fail的消息,则告知user1@region1/desktop
  • 如果任何一个SM收到RoutingKey=group.group1.receive的消息,则根据群组元数据,下行消息给当前SM管理的所有在线群组成员
  • 如果Broker收到RoutingKey=group.group1.receive的消息,则判断其他Region是否存在group1的在线用户,如果存在,则下行消息给对应Region的Broker,否则,丢弃该消息

如果Broker收到其他Region的下行消息,则直接Publish RoutingKey=group.group1.receive到Exchange,不再走Auditor

BindingKey:

  • SM的BindingKey,正则表达式:^(user|group){1}.[a-zA-Z0-9@/]{32,}.(receive|audit-fail){1}$
  • Auditor的BindingKey,正则表达式:^user.[a-zA-Z0-9@/]{32,}.(send){1}$
  • Recorder的BindingKey,正则表达式:*.*.*
  • Broker的BindingKey,正则表达式:^(user|group){1}.[a-zA-Z0-9@/]{32,}.(receive){1}$
im-rabbitmq-design.png

4. 小结

下文将介绍IM系统分布式部署方案。

你可能感兴趣的:(IM - 核心功能之消息收发和MQ设计)