# 第 10 章：会话谁来建

> Ana 在新电脑上第一次登录桌面版，左边的会话列表里该有什么？会话列表是手机从收到的消息里自己拼出来，还是服务器建好、设备去同步？

深入理解 IM 系统 · https://im.liko.page/zh/fan-out/

v2 的第一件事是桌面版。Ana 买了台新笔记本，第一次登录，左边的会话列表该出现什么？

她加了很多群，有 **2,000 个会话**（全书平均每人 200 个）。不少群很安静：家人群一个多月没人说话，老同学群快五个月了。

这些会话从哪来，取决于**会话列表是谁建的**。第 6 章已经在服务端给每人每个会话存了一行记录，新设备照着它就能拿全。这一章把它定成规矩，并说清楚为什么不走另一条路：让每台设备自己从消息里拼。

## 1. 两种建法

*（互动图：请在网页上查看 https://im.liko.page/zh/fan-out/）*

- **端上建**：服务端给每人一条时间线，也就是信箱，发给你的每条消息按时间记一条小记录（哪个会话、第几条，32 字节）。手机把它们按会话归堆，就是会话列表。
- **服务端建**：服务端给每人每个会话存一行会话记录，手机照抄。

## 2. 和扩散连在一起

**端上建，离不开写扩散。** 手机只能从收到的消息里知道有哪些会话，所以每条消息都得往每个收件人的时间线里追加一条，这叫写扩散。徒步群 500 人，一条消息追加 500 条；一天 1,000 条消息，就是 50 万条。时间线只会越来越长，得定期清。

**服务端建，消息可以只存一份。** 名单在服务端，消息只放在会话里（读扩散），徒步群一条消息，不用给成员写任何东西。要不要另外再给每人留一条流，是第 6 章算过的读写账，当时选了不留。

Telegram 是服务端建、又留着流的例子：会话列表由服务端给（[`messages.getDialogs`](https://core.telegram.org/method/messages.getDialogs)），私聊和普通群另外共用每人一条[更新序列](https://core.telegram.org/api/updates)。

## 3. 新电脑第一次登录

端上建，新电脑只能**重放时间线**：把信箱拉下来，按会话归堆。归得出多少，看信箱留了多久：

- **留得短**（比如 7 天，省存储）：几个月没人说话的群，时间线里没有它的记录，就归不出来。
- **一直留着**：归得全，但要先把历史全拉下来。Ana 一天收 267 条，一年的记录约 3.1 MB，用得越久越大。

服务端建，新电脑**照抄会话**：2,000 行，用一年和用五年一样大。

一句话：**时间线随消息涨，会话随会话数涨**。新设备要的是会话，照抄比重放省事。

*（互动图：请在网页上查看 https://im.liko.page/zh/fan-out/）*

信箱留 7 天，新电脑只归出 380 个会话，家人群、老同学群都不在。换成服务端建，2,000 个都在。

置顶、免打扰这些会话上的设置，是另一套同步逻辑，这一章不比。

## 4. v2 的决定

**会话列表以服务端为准：服务端存会话（会话记录），每台设备照抄，本地只是副本**。消息仍然只在会话里存一份。

## 5. 代价

存的东西没有变多，会话记录第 6 章就有。新的代价在设备上：

- **新设备第一次要拿全部会话。** 每个会话一行记录加最新 seq（36 字节），再各拉最新一条消息（约 200 字节），2,000 个会话约 472 KB。可以先拉第一屏，往下翻再拉。
- **本地那份会和服务端对不上。** 离线时删了一个会话，或者同步漏了一次。规矩是以服务端为准，改回来。

还没解决的是第 6 章那笔：**每次同步都问遍所有会话**，Ana 一次 24 KB。这是下一章的事。

## 6. 其他答案

- **信箱加端上建。** 服务端简单，同步只有一条流、一个来回。代价是第 3 节那些：留得短归不全，留得长要重放很多历史；会话上的设置还得另外同步。
- **服务端建，也留每人一条流。** 像 Telegram，私聊和小群一次拿到“上次之后的全部”。两套同步要一起维护，群从小变大还得换一种。

## 7. 这一章的决定

*（互动图：请在网页上查看 https://im.liko.page/zh/fan-out/）*

**决策卡**

- 问题：v2 有了桌面版。Ana 在新电脑上登录，会话列表从哪来？她有 2,000 个会话，很多群几个月才说一句。
- 选择：会话列表以服务端为准：服务端存会话（第 6 章的会话记录），不是一条时间线；每台设备照抄，本地只是副本。消息仍然只存一份。
- 代价：新设备第一次要拿全部会话（2,000 个约 472 KB，可以先拉第一屏）；本地那份要以服务端为准改回来。还没解决：每次同步仍问遍所有会话。
- 什么时候重新考虑：只拿变了的会话（第 11 章）；已读和未读（第 15 章）；几台设备（第 16 章）。
- 其他答案：信箱加端上建（留得短归不全，留得长要重放历史）；服务端建，也留每人一条流（Telegram）。

会话在服务端，几台设备都对得上了。可 Ana 每次打开手机，还是要下载 2,000 个会话的最新 seq，其中只有十来个变了。下一章：会话同步。
