# 前言
作者一直认为一个优秀的程序员不仅 仅是具有设计架构的能力,更是了解整个行业背景的现状和趋势。为了更好的设计和架构一个大型系统,我们需要调研行业的背景,从一个具象行业抽象出两个核心:领域模型和抽象流程。下面这章会介绍IM系统的 会话 和 消息 两大核心概念, 以及IM系统的基本抽象流程。
# 会话和消息两大核心概念
笔者认为两个核心的概念是 会话 和 消息 的概念
- 会话session(conversation): 它是指AB通讯之间维持的一种关系,它是消息存储的载体。
- 消息message: 可以根据业务分为两大块消息,会话内消息和系统通知消息。会话内消息又可以分为基本消息和自定义消息。
# 会话
即时通讯 SDK 的核心概念「会话」,即 Conversation。我们将单聊和群聊(包括聊天室)的消息发送和接收都依托于 Conversation 这个统一的概念进行操作。如下是定义会话数据结构
# 会话数据格式
| 会话属性 | 备注 |
|---|---|
| id | 会话ID |
| scene | 场景 |
| to | 聊天对象,账号或者群ID |
| updateTime | 会话更新时间 |
| unread | 未读数 |
| lastMsg | 此会话的最后一条消息 |
| custom | 扩展Json字符串 |
# 消息
IM SDK内的消息可以分为两类:会话内消息和系统消息。
# 会话内消息
会话内消息只能出现并展示在聊天界面里,一般是应用内的一个用户发给另一个用户(或群组/聊天室)的消息,例如文本消息、图片消息都属于会话内消息。:
| 会话内消息类型 | 备注 |
|---|---|
| 文本消息 | 消息内容为普通文本 |
| 图片消息 | 消息内容为图片URL地址、尺寸、图片大小等信息 |
| 语音消息 | 消息内容为语音URL地址、时长、大小、格式等信息 |
| 视频消息 | 消息内容为视频文件的URL地址、时长、大小、格式等信息 |
| 文件消息 | 消息内容为文件的URL地址、大小、格式等信息,格式不限 |
| 地理位置消息 | 消息内容为地理位置标题、经度、纬度信息 |
| 通知消息 | 自定义消息可以用于消息接入扩展。 例如卡片消息,红包消息等。 |
| 自定义消息 | 通知消息属于会话内的一种消息,用于会话内通知和提示场景。例如:群名称更新、某某某退出了群聊等。 |
# 消息数据格式
| 属性 | 类型 | 描述 |
|---|---|---|
| conversationId | String | |
| id | String | 服务器用于区分消息用的ID |
| idClient | String | SDK生成的消息id, 在发送消息之后会返回给开发者, 开发者可以在发送消息的结果回调里面根据这个ID来判断相应消息的发送状态, 到底是发送成功了还是发送失败了, 然后根据此状态来更新页面的UI。如果发送失败, 那么可以重新发送此消息 |
| scene | String | 群聊还是单聊场景 |
| type | String | 消息类型:文本,图片,语音,还是自定义消息 |
| from | String | 消息发送方 |
| to | String | 消息接收方 |
| time | Number | 消息时间戳 |
| flow | String | 消息的流向 'in'表示此消息是收到的消息,'out'表示此消息是发出的消息 |
| status | String | 消息发送状态 'sending': 发送中, 'success': 发送成功,'fail': 发送失败 |
| content | String | 文本消息的文本内容, 请参考发送文本消息 |
| file | Object | 文件消息的文件对象, 具体字段请参考 |
| resend | Boolean | 是否是重发的消息 |
| custom | String | 扩展字段, 用途扩展自定消息 |
# 系统消息
系统通知一般在会话维度,通常用于验证关系。例如:某某某请求加你为好友,群名称更新、某某某退出了群聊等
# 系统消息数据格式
| 属性 | 类型 | 说明 |
|---|---|---|
| msgId | String | 消息Id |
| time | Number | 时间戳 |
| type | String | 系统通知类型 |
| from | String | 系统通知的来源, 账号或者群ID |
| to | String | 系统通知的目标, 账号或者群ID |
| scene | String | 自定义系系统通知的场景, 参考[消息场景] |
| content | String | 文本消息内容 |
| custom | String | 自定义消息内容,JSONString格式 |
# 基本流程
IM即时通讯是不同用户之间交流的双通通道,如下是收发消息的简单模型。

客户端A向客户端B发消息,内部流程应该如下:
- 客户端A和客户端B都先和服务端建立 WebSocket的长连接。
- 客户端A通过Websocket向服务端发送了文本消息,同时服务端向客户端A发送一个ACK回包,说明收到此消息。
- 服务分析此消息的来源和去向,消息类型和内容。通过 Websocket 投递给客户端B
- 客户端B收到消息的回调。完成一次客户端A向客户端B发消息的流程
IM系统一次完整用户建立连接的流程图:
- 输入用户基本信息,如果有固定秘钥或者
Token则初始化信息,建立连接。 - 没有
Token则通过https根据用户信息往服务端申请Token<
