如何设计一个IM单聊架构( 三 )


拉模式适合的场景如下:
 

  1.  
    设备初始化时:先拉取会话列表,在根据会话的列表来为每个会话拉取一定的消息记录 。可以通过控制拉取的数据量,减轻服务端压力 。
     
  2.  
    历史聊天记录:按需拉取一定条数的记录,用户向上翻取记录再拉取固定条数的记录,直到翻到没有记录(就是翻页) 。
     
 
推模式适合的场景如下:
 
  1.  
    用户实时接收消息
     
  2.  
    用户在线,有未读消息做通知栏push时
     
五. 消息流转 
上面确定好推拉模式后,我们来看发消息和收消息都有哪些业务逻辑执行 。
发消息
如何设计一个IM单聊架构

文章插图
如上图所示,大致可分为三步
1. 消息过滤
首先用户的消息通过客户端的SDK发送出来,通过长链接到达了「逻辑层」,逻辑层接收到该请求后,可以根据定义的拦截过滤规则调用「服务层」的服务接口,来对消息进行处理;
2. 消息补充
处理通过后,来对消息的发送方资料进行填充,简单来说就是senderId标识,接收方接收消息时能够填充到对应的会话中 。
3. 派发任务
消息实体处理完成后,将该消息push到「服务层」的「异步任务队列」服务中 。
异步队列任务主要需要做以下四个方面的操作
 
  1.  
    更新存储端的「聊天记录」
     
  2.  
    更新会话的「消息总数量」,用来计算未读计数
     
  3.  
    根据接收方的在线状态来判断,是直接进行push,还是存入到离线列表中,等待用户上线后再进行消息拉取
     
  4.  
    更新「会话列表」的score值
     
具体异步队列还可以细化拆分,例如 实时任务队列 延时任务队列 失败重试队列 分别启动不同的线程池来消费任务,按需分配线程数处理

收消息 
收消息主要有以下几个场景需要处理
 
  1.  
    客户端需要将消息append到聊天列表中,并在会话列表中将该会话增加未读消息标识 。
     
  2.  
    如果接收方打开了开聊天窗口,客户端会发送一个消息的ACK给服务端,来标记该消息已读 。
     
  3.  
    服务端收到已读ACK后需要更新「已读计数」相关数据项
     
  4.  
    如果是拉取离线消息,服务端还需要更新「离线消息」相关数据项
     
 
小结
本文从五个方面来对单聊的IM架构进行了设计分析
 
  1.  
    业务功能拆分
     
  2.  
    数据结构设计
     
  3.  
    系统结构设计
     
  4.  
    推拉模式选择
     
  5.  
    消息流转分析 讲了基础的结构有哪些,数据结构有哪些要求,以及消息流传的过程是什么样的 。
     
 
对im单聊场景的开发框架有了大体的一个认识,但是实际落地的时候还有很多细节需要去实现 。




推荐阅读