升级指南
本页覆盖三类升级:服务端(替换二进制 + 数据目录)、Web SDK/IMKit(1.x 手写 DOM → 2.0 组件层,以及错误码校正)、Electron(main/preload/renderer 三处同版本升级)。契约策略是 additive-only:v1.x 只新增可选字段、接口、事件与错误码,不改名/不删字段/不改语义。
IDL:v1.0.0,冻结修订号以 /docs/changelog 为准。Web IMKit:VERSION="2.0.0"、IMPL_IDL_VERSION="1.0.0"。服务端能力以 GET /api/__contract/introspect 为准。
概念
兼容策略
- additive-only:新增可选字段、枚举值、接口/事件/错误码;禁止改名、改语义、删除、改数值;破坏性变更走 v2。
- 服务端错误响应保持
{code,msg?,data?,requestId?}信封;新增字段不影响旧客户端。 - 文档与契约快照都由同一 IDL 生成;升级后必须重新执行零漂移校验。
2.0 的破坏性变化(Web SDK/IMKit)
| 变化 | 1.x 旧行为 | 2.0 新行为 | 迁移动作 |
|---|---|---|---|
| 网络错误码 | 历史版本 SDK_NETWORK 曾为 3001 | SDK_NETWORK_ERROR=3003;3001 现在是 SDK_NOT_CONNECTED | 按常量名判断,不按数字硬编码;旧别名 SDK_NETWORK 仍等于 3003 |
| 超时错误码 | 旧版本号语义不统一 | SDK_TIMEOUT=3002 | 用 ErrorCode.SDK_TIMEOUT |
| UI 层 | 宿主手写 DOM/样式 | IMKit 组件层(列表/聊天/气泡/输入区/主题/门面) | 可增量接入;先替换列表或聊天视图,不必一次全换 |
| 主题 | 散落 CSS 覆盖 | Theme + --imkit-* 变量 | 把品牌色收敛到 Theme,删除硬编码颜色 |
| 错误信封 | 部分旧接口返回裸对象 | 统一 {code,msg,data,requestId} | 统一读 result.code === 0 与 result.data |
服务端升级
- 数据目录
IM_DATA_DIR是唯一持久化位置(PostgreSQL 模式用IM_DATABASE_URL);升级前必须备份。 - 启动时可用
IM_DATA_LOCK=0关闭目录锁(不推荐并发启动两个实例)。 - 维护周期
IM_MAINTENANCE_MS(默认 5000ms)影响封禁到期、告警评估、token 过期清理等;升级后保持原值。
Electron 升级
- Electron 是 main(IMLib + 本地 SQLite)/ preload(白名单桥)/ renderer(薄代理)三层,必须同版本一起升级。
- 升级后确认 Electron 版本满足
node:sqlite(随 Electron 35 / Node 22 提供),无需额外重建 SQLite 原生依赖;核对 preload 暴露的方法白名单与新 IMLib 方法一致。 - 本地 SQLite 命名空间(
imlib.localDbNamespace)保持稳定;改命名空间等于放弃旧本地历史。
前置条件
- 已确认当前版本:
/health、/api/__contract/introspect、manifest.json与 SDKVERSION。 - 有可回滚的旧二进制与旧 SDK 包;数据目录/数据库已完成备份。
- 有隔离环境可先跑契约校验与冒烟。
- 升级窗口内可接受 WS 断开重连;客户端应已实现指数退避重连。
步骤
- 盘点版本与差异
记录服务端 IDL freezeRevision、Web SDK
VERSION、Electron 三处版本;阅读 更新日志 与对应 Release Notes。 - 在隔离环境先升级服务端
备份
IM_DATA_DIR→ 替换二进制 → 用相同环境变量启动 →/health与 introspect 校验 → 跑契约校验与消息/回调冒烟。 - 升级 Web SDK 与错误码处理
替换
sdk/web产物;把按数字判断的错误码改为常量;确认 3001 不再被当作“网络错误”。 - 增量接入 IMKit(可选)
先接
ConversationListView或ChatView,保留旧自绘区域;主题用Theme收敛,避免一次性重写。 - 升级 Electron 三处
main/preload/renderer 同版本发布;确认 Electron 版本满足
node:sqlite;验证本地 SQLite 读写与 preload 白名单。 - 回归与观察
验证建连/重连、收发、已读、回调、推送、管理端关键路径;观察错误率与
online_drop告警。 - 回滚预案
停止新版本 → 恢复旧二进制与匹配的数据目录 → 回退 SDK 包;契约 additive-only 下旧数据可被新版本读取,反向回滚需确认新字段被旧版本忽略。
参数表
| 项 | 入口 / 变量 | 用途 |
|---|---|---|
| 服务端地址 | IM_ADDR(默认 127.0.0.1:8080) | 监听地址 |
| 数据目录 | IM_DATA_DIR | 持久化快照/上传文件 |
| 数据库 | IM_DATABASE_URL | PostgreSQL 模式;为空走文件快照 |
| 管理密钥 | IM_ADMIN_SECRET | Admin API 鉴权 |
| 维护周期 | IM_MAINTENANCE_MS | 封禁到期/告警评估等 |
| 翻译/Agent 端点 | IM_TRANSLATE_ENDPOINT、IM_AI_ENDPOINT | 外部服务代理;未配置返回 1021 |
| CORS | IM_CORS_ORIGINS | 浏览器跨域白名单 |
| 健康检查 | GET /health | 存活探针 |
| 契约自省 | GET /api/__contract/introspect | 运行时 operation/事件/错误码 |
示例
升级前快照
curl -sS http://127.0.0.1:8080/health
curl -sS -H "X-Admin-Secret: dev-admin" http://127.0.0.1:8080/api/__contract/introspect > introspect-before.json
# 备份数据目录(示例)
cp -a "$IM_DATA_DIR" "$IM_DATA_DIR.bak.$(date +%Y%m%d%H%M)"升级后校验
curl -sS http://127.0.0.1:8080/health
curl -sS http://127.0.0.1:8080/api/__contract/introspect > introspect-after.json
node -e "const a=require('./introspect-before.json'),b=require('./introspect-after.json');
console.log('operations', (a.operations||[]).length, '->', (b.operations||[]).length);
console.log('errors', (a.errors||[]).length, '->', (b.errors||[]).length);"错误码迁移(JS)
import { ErrorCode } from '@ni-paas/im-web/rongim';
// 错误:按数字判断,3001 在 2.0 已表示“未连接”
// if (err.code === 3001) showNetworkError();
// 正确:按语义常量判断
if (err.code === ErrorCode.SDK_NETWORK_ERROR) showNetworkError(); // 3003
if (err.code === ErrorCode.SDK_NOT_CONNECTED) showReconnectTip(); // 3001
if (err.code === ErrorCode.SDK_TIMEOUT) showTimeoutTip(); // 3002
// 旧代码若仍使用 SDK_NETWORK,它等价于 SDK_NETWORK_ERROR(3003)
console.log(ErrorCode.SDK_NETWORK === ErrorCode.SDK_NETWORK_ERROR); // trueElectron 同版本发布(package.json 片段)
{
"name": "ni-paas-im-electron",
"version": "2.0.0",
"main": "src/main/index.mjs",
"devDependencies": {
"electron": "^35.0.0"
},
"scripts": {
"test": "node --test test/*.test.mjs"
}
}常见问题
必须迁移到 IMKit 吗?
不必须。IMLib 的公开 API 保持兼容;IMKit 是 2.0 新增的组件层,可增量接入。
3001 到底表示什么?
2.0 起 3001 是 SDK_NOT_CONNECTED(未连接/重连中);网络错误是 3003。SDK_NETWORK 旧别名仍指向 3003。
升级服务端会丢数据吗?
additive-only 下不应丢;仍必须备份 IM_DATA_DIR。PostgreSQL 模式请同时备份数据库。
能只升级 Electron renderer 吗?
不能。main/preload/renderer 必须同版本;否则 preload 白名单与 IMLib 方法可能不匹配。
如何确认运行时与文档一致?
用运行时自省接口比对运行时与契约;文档由同一 IDL 生成,可做零漂移校验。
回滚要注意什么?
旧版本会忽略新增字段(additive-only),但新版本写入的新字段在回滚后不可见;回滚前先确认业务不依赖这些字段。