虚构 IM 业务地图:沿一条消息理解系统
2026/9/23...大约 5 分钟
从两个用户的一段交流开始
用户 u-a 希望给 u-b 发一句话,u-b 在线时能看到,离线后回来能继续交流。随后加入群组 g-study、第二台设备、历史查询、已读状态和故障恢复。所有身份与数据均为教学设定。
课程以 OpenIM为公开项目参照,先建立足够小的程序模型,再逐步对照源码。当前教学模型的规则会写清楚;是否对应上游功能与保证,需要具体源码和配置支持。
先认识这些对象
| 对象 | 初学时怎样理解 | 后续要深化的边界 |
|---|---|---|
| 用户 | 交流中的一个身份 | 登录凭据、权限和账号生命周期 |
| 设备 | 某个用户使用的一个客户端实例 | 一个用户多台设备、旧连接与新连接 |
| 会话 | 一组交流关系及其消息历史的归属 | 单聊、群聊、成员变更和可见范围 |
| 消息 | 一次发送的内容及必要标识 | 内容类型、顺序、重复、删除与撤回 |
| 连接 | 客户端与服务端通信的通道 | 建立、心跳、断开、重连和资源释放 |
| 进度 | 已处理到哪里的一份状态 | 接收、补拉与已读是否按用户或设备记录 |
最初只使用文本消息。附件、搜索、撤回和其他内容类型在具备存储、权限与协议基础后展开;音视频媒体链路需要另外的协议与资源课程,按方向继续深化。
需求增加时,知识怎样跟上
| 新增需求 | 本课先问什么 | 理论与学习位置 |
|---|---|---|
| 显示并校验一条消息 | 字符串、ID、字节数和合法输入分别是什么? | S0:类型、表达式、条件与函数 |
| 管理多条消息 | 如何列表、查找、复制和修改? | S1:集合、结构体、指针、算法与测试 |
| 保存本地历史 | 文件格式错误或写入失败时怎么办? | S1:I/O、错误、资源和格式兼容 |
| 两人在线通信 | 消息如何经过网络,连接由谁读写和关闭? | S2:进程、HTTP/WebSocket、基本并发 |
| 登录与会话权限 | 服务端怎样确认发送者有资格参与会话? | S3:身份、授权、输入和数据访问 |
| 查询持久历史 | 怎样存储、索引、分页,失败时确认了什么? | S3/S4:SQL、MongoDB、事务与恢复 |
| 群聊与慢设备 | 一次发送产生多少投递工作,队列能否无限增长? | S4:算法、运行时、背压和测量 |
| 断线后补齐消息 | 从哪个位置开始,怎样知道有缺口和已到末尾? | S5:序号、分页、状态与同步 |
| 重试与多端 | 同一意图重复发送时如何识别,不同设备怎样协调? | S5:身份、去重、顺序、已读与会话同步 |
| 多节点与异步 | 入队、存储、推送和通知之间怎样恢复? | S5:部分失败、队列、复制与对账 |
| 网关升级和扩容 | 老连接怎样退出,新连接怎样接入? | S6:生命周期、发现、容量与发布 |
| 大群和旧客户端 | 新要求怎样改变扩散、存储、协议与成本? | S7:设计比较、迁移、验证与长期维护 |
一个“成功”需要拆成哪些问题
学习时分别定义:服务端是否受理,约定的持久条件是否满足,接收设备是否处理,用户是否已读。它们发生在不同位置,有不同证据与失败可能。
例如 u-a 没收到发送响应,可能是请求未到达,也可能已经受理但响应丢失。此时是否重试、用什么身份重试、如何查询结果,都需要明确规则。课程会从小例子逐步推导,相关源码观察见 OpenIM 的发送与存储边界。
这些教学状态用于讨论需求,不自动意味着上游为每个阶段都提供同名 API。具体接口和配置按固定版本核对。
会逐步加入的失败用例
- 文本为空、格式不合法或超过当前规则的大小限制。
- 伪造发送者、访问无权查看的会话、退群后继续发送。
- 发出后没有响应,再次提交同一发送意图。
- 连接在消息交付中途断开,重新连接后需要补齐。
- 同一用户两台设备同时在线,接收与已读进度不同。
- 消费进程、数据库或推送链路中途失败。
- 热点群或慢设备造成积压,节点恢复后形成突发流量。
每次只增加已经具备前置的失败条件,要求解释输入、状态、可观察结果和恢复路径。
一张 IM 需求记录表
谁希望给谁发送或查询什么:
用户、设备、会话、消息分别怎样标识:
这次输入与当前状态:
成功具体承诺到哪一步:
哪些条件应该拒绝:
响应丢失或重复到达时怎样判断:
失败后还保留哪些事实:
本次小模型尚未加入哪些条件:
对应源码版本、文件与已读范围:初学时先填“校验一条文本消息”,网络、重试和多端部分暂记为后续主题。完整顺序见IM 学习路线。