Skip to content

legacy 与 strict ​

Talkwire 服务端按两档之一回答客户端:legacy 与参考服务逐帧一致,strict 在此之上修正已知缺陷、新增字段和动作(规范第 0.3 节)。默认是 strict;迁移原版项目、要与旧客户端逐帧兼容时用 legacy。

参考服务指原版 IM 服务,它有若干已知缺陷,编号 D1–D9(规范第 18 节)。两档的区别全部来自是否保留这些缺陷,以及 strict 档新增的字段和动作。

各档保证什么 ​

两档对客户端的承诺不同,适用的项目也不同。

档位保证适用
legacy对所有黄金对话逐帧一致,包括缺陷行为(规范第 0.3 节);接受参考服务接受的全部令牌(ADR-0002 决定 3)迁移原版项目,现网旧客户端不升级就能连上
strict修正第 18 节的缺陷(D6 除外),其余与 legacy 一致;新增的字段旧客户端忽略即可(规范第 0.3 节)新项目,以及旧客户端已全部换完的迁移项目

strict 档仍用同一套黄金对话检验:比较前去掉新增字段后须逐帧一致,有意偏离的 6 个场景改用另录的版本(规范第 19 节)。所以 strict 不是另一套协议,而是 legacy 加上新字段、新动作和缺陷修正。

怎么选 ​

用环境变量 TALKWIRE_PROTOCOL_PROFILE 选档,取值 legacy 或 strict,不设时是 strict(规范第 0.3 节)。其他取值会让服务端启动失败(server/config.go)。

迁移原版项目的顺序是“先换服务端(legacy)、再换客户端、最后切 strict”(ADR-0002)。换服务端时设 legacy,现网客户端看到的帧不变;旧客户端淘汰后再改成 strict。具体步骤见从现有 IM 系统迁移。

令牌校验随档位变化,另有两个开关(ADR-0002 决定 3):

环境变量作用
TALKWIRE_TOKEN_USER_ROLESstrict 档接受的令牌 role,默认 app_user;令牌还必须是 type=access(红线 R18)
TALKWIRE_ACCEPT_LEGACY_TOKENS设为 1 时 strict 档也接受全部令牌,供迁移期间使用。默认关,开着时服务端启动打印警告

其余环境变量见环境变量。

不分档位的功能 ​

多端同时在线、可选模块、推送服务商两档都有,只在客户端用到新字段时启用(ADR-0002 决定 4)。例如不带 device 登录时,两档都与参考服务一样让同一账号的连接互相顶替(规范第 0.3、6.2 节)。

模块未安装时,模块动作在两档下都得到 501 module not enabled: <模块名>(规范第 4.1 节,server/modules.go)。宿主触发的 custom_update 推送也不分档位(规范附录 B)。

strict 档的三类改动 ​

strict 档相对 legacy 只做三类改动(规范第 0.3 节)。

新增字段 ​

新增字段只加不改,旧客户端忽略即可。

字段出现在节
id成功的 login 应答、pres 快照应答规范第 3.3 节
protocol、capabilities、vapidKey成功的 login 应答;vapidKey 只在配置了 Web Push 时出现规范第 6.1 节
errCodeaction 帧族的错误帧规范第 4.3 节
readSeqget 应答,表示本人在该会话已读到的 seq规范第 9.3 节

readSeq 背后还有一处行为:strict 档把单聊的 read 存为发送者本人的已读位置,legacy 档不存(规范第 12.3 节)。

新增动作 ​

新增动作在 capabilities 里宣告,旧客户端不会发出(规范第 0.3 节)。目前只有 sync_summary,宣告为能力 sync-summary(规范第 8.1 节)。

legacy 档对它像参考服务一样回 400 unknown action: sync_summary。用法见同步与补拉。

修正缺陷 ​

strict 档修正了第 18 节中 D6 以外的全部缺陷;D6 两档相同,留给协议 v2(规范第 0.3、18 节)。修正方式与客户端应对见已知缺陷。

编号参考服务的行为修正的档位
D1leave_grp 不校验成员关系:非成员也得到 200,并让全群收到一条 from 为陌生人的 grp_syncstrict
D2leave_grp 对单聊 topic 生效,把自己移出单聊strict
D3pres 可以查询任意 uid,包括陌生人strict
D4登录接受刷新令牌、管理员令牌等非访问令牌strict
D5补投的 grp_sync 带入队时的旧群名strict
D6单聊的 recalled、info 的 topic 照抄请求,可能是接收方自己的 uid不修正,两档相同
D7不需审核的扫码入群既不通知群成员,也不给入群者推 grp_sync、不订阅strict
D8group_join_review 先把申请标为已处理再做检查,检查失败时申请被白白消耗strict
D9入群申请与审核结果的离线事件从不入队strict

客户端怎样同时兼容两档 ​

客户端必须在两档下都能正常工作:不依赖任何缺陷行为,对缺陷可能产生的帧做容错(规范第 0.3 节)。落到代码上是下面几条。

差异客户端做法出处
成功 login 与 pres 快照是否带 id先按 id 匹配,匹配不到再按 action 关联规范第 3.3 节
错误帧是否带 errCode有 errCode 时按它判断;没有时按 code,不解析 reason 文本规范第 4.1、4.3 节
新动作与新字段先看 capabilities:有 sync-summary 才发 sync_summary,有 multi-device 才带 device规范第 6.1、6.2、8.1 节
get 应答是否带 readSeq带时推进本地已读位置;不带时(legacy)只靠本地记录规范第 8 节第 5 步
缺陷行为按第 18 节“客户端应对”一列处理规范第 18 节

两档的一致性检验 ​

legacy 档由对参考服务录制的 33 个黄金对话逐帧把关(ADR-0002 决定 5)。strict 档用同一套对话,比较前去掉新增字段(id、protocol、capabilities、vapidKey、errCode、readSeq),并对有意偏离的场景改用 contract/protocol/transcripts-strict/ 里另录的版本(规范第 19 节):

场景对应缺陷
core/login-tokensD4
core/presenceD3
core/leave-grpD1、D2
core/group-offline-eventsD5
module/qr-joinD7
module/qr-join-reviewD8

D9 没有另录的对话,由服务端单测 TestD9_JoinReviewQueuedForOfflineApplicant 覆盖(docs/protocol-findings.md F59)。检验命令见协议概述。

核心以 Apache-2.0 发布;端到端加密模块为 AGPLv3。