10 KiB
SimCAE Hub 客户端接入、打包和部署指南
本文说明 update-client 的当前实现。它保留 Launcher / Updater / Bootstrap 的桌面客户端机制,服务端协议使用 SimCAE Hub 当前 Go API。
1. 适用范围
当前客户端只覆盖项目已有页面和接口对应的能力:
- 产品版本、软件发布、发布包和 Manifest。
- 客户授权、在线命名用户席位和门户受控下载。
- 在线检查更新、Manifest 拉取、受控下载、SHA-256 校验。
- Manifest 签名验签、临时文件、断点重试、安装前后完整性校验。
邮箱、支付、灰度、告警等页面上没有的能力不属于当前范围。崩溃报告是 SimCAE Hub 保留的旧系统兼容后端接口,不属于 Launcher / Updater / Bootstrap 的更新链路;接入方需要崩溃上报时,按项目根目录 项目细节.md 里的崩溃报告接口说明调用。
2. 客户端程序组成
| 程序 | 作用 |
|---|---|
Launcher |
客户日常启动入口,负责导入配置、使用 client_token 检查更新、启动 Updater 或主程序 |
Updater |
负责拉取 Manifest、下载发布包、校验文件、准备安装事务 |
Bootstrap |
负责在需要替换运行中文件时接管安装,并把结果交回 Updater |
MainApp |
示例主程序,用来验证 launch ticket 和安装后完整性校验 |
Common |
配置、HTTP、票据、完整性校验等公共代码 |
3. 当前在线更新链路
Launcher启动后读取服务端生成的config/app_config.json,并把静态配置导入当前用户的运行配置。- 如果配置里没有
api_base_url,客户端会回退到编译进 EXE 资源中的server_config.json。 Launcher确保存在device_id,并检查client_token是否存在。Launcher调用GET /api/v1/client/update/authorized-check,请求头带X-Client-Token。- 如果服务端返回可用发布,
Launcher启动Updater,并传入产品编码、渠道、目标版本和发布 ID。 Updater调用GET /api/v1/client/update/manifest,请求头继续带X-Client-Token。Updater先校验服务端返回的manifestSha256,再按配置决定是否强制要求 RSA-SHA256 签名。Updater从 Manifest 中读取每个文件的downloadUrl、sizeBytes和sha256。- 下载请求统一带
X-Client-Token。 - 下载使用
.part临时文件保存进度,请求失败后按网络重试策略处理。 - 文件下载完成后,客户端按 Manifest 校验文件大小和 SHA-256。
- 安装前校验 staging 目录,安装完成后保存 Manifest 缓存,并可在主程序启动时再次校验已安装文件。
4. 关键配置字段
正式客户安装包里的 config/app_config.json 由服务端在上传发布包 ZIP 时自动生成。常用字段如下:
| 字段 | 说明 |
|---|---|
product_code |
SimCAE Hub 后台产品目录中的产品编码,例如 stage2-dap |
app_id |
本地应用标识,默认和产品编码一致 |
channel |
发布渠道,例如 stable |
current_version |
当前本地安装版本,例如 1.0.0 |
api_base_url |
后端 API 地址,例如 http://192.168.1.158:18000 |
client_token |
Launcher/Updater 调更新接口使用的部署级令牌,不绑定某一个客户 |
install_root |
相对 Launcher/Updater 所在运行目录解析的更新根目录,决定 Updater、Bootstrap 和启动校验作用在哪棵目录 |
main_executable |
相对运行目录解析的业务入口程序,通常是 MainApp.exe 或真实软件入口 |
launcher_executable |
相对运行目录解析的 Launcher 文件名,主要用于提示和保持启动链路配置一致 |
updater_executable |
相对运行目录解析的 Updater 文件名,Launcher 检查到更新后会启动它 |
bootstrap_executable |
相对运行目录解析的 Bootstrap 文件名,Updater 需要替换文件时会启动它 |
platform |
操作系统,例如 windows 或 linux |
arch |
架构,例如 x86_64 |
abi |
ABI,例如 msvc;没有时可留空 |
launch_token |
Launcher 和 MainApp 之间生成一次性启动票据的本地密钥 |
require_manifest_signature |
是否强制要求 Manifest 必须带签名 |
verify_installed_on_start |
主程序启动时是否按 Manifest 缓存校验已安装文件 |
config/server_config.json 会编译进客户端资源,作为 api_base_url 缺失时的兜底地址,当前测试服务器地址为:
http://192.168.1.158:18000
如果换服务器,可以改完该文件后重新编译客户端;正式客户包通常由服务端写入 api_base_url,不需要把 server_config.json 暴露给客户。
5. 编译和打包 SDK
客户端编译、带 Qt 和不带 Qt 两种 SDK 打包方式、输出目录、输出 ZIP 文件名,统一维护在 ../打包成SDK.md。
本文件只说明 SDK 在客户软件里的接入位置和运行逻辑,不重复维护打包命令。
SDK 包不会包含最终 app_config.json、server_config.json、server_config.qrc 或 manifest_public_key.pem。这些最终配置在完整客户软件包或 Qt IFW 交付包上传到 SimCAE Hub 后由服务端生成。
6. 客户安装包配置
接入方应把以下文件放到客户软件目录的根目录或 bin/ 目录:
LauncherUpdaterBootstrapMainApp或真实业务主程序config/目录,可以先为空
6.1 标准目录结构和路径口径
更新系统不要求必须放在客户软件根目录。它可以放在 SimCAE/ 根目录,也可以放在 SimCAE/bin/ 目录。关键是让客户端配置里的 install_root 和服务端 Manifest 文件路径使用同一套口径。
先区分三个目录概念:
| 概念 | 说明 |
|---|---|
| 运行目录 | Launcher、Updater、Bootstrap 所在目录,由客户端自动识别 |
install_root |
相对运行目录解析的更新根目录,Updater 下载、校验、备份、回滚和 Bootstrap 替换文件都以它为范围 |
Manifest files[].path |
服务端生成的安装相对路径,客户端会把它拼到 install_root 下面 |
目录结构一:更新系统放在软件根目录。
SimCAE/
Launcher.exe
Updater.exe
Bootstrap.exe
MainApp.exe
config/
app_config.json
App/
...
对应配置:
{
"install_root": ".",
"main_executable": "MainApp.exe",
"launcher_executable": "Launcher.exe",
"updater_executable": "Updater.exe",
"bootstrap_executable": "Bootstrap.exe"
}
目录结构二:更新系统和启动入口放在 bin/。
SimCAE/
bin/
Launcher.exe
Updater.exe
Bootstrap.exe
MainApp.exe
config/
app_config.json
App/
...
如果希望整个 SimCAE/ 都属于更新范围,对应配置:
{
"install_root": "..",
"main_executable": "MainApp.exe",
"launcher_executable": "Launcher.exe",
"updater_executable": "Updater.exe",
"bootstrap_executable": "Bootstrap.exe"
}
这表示 Launcher 从 bin/ 启动 MainApp.exe,Updater 和 Bootstrap 更新的是 bin/ 的上一级,也就是整个 SimCAE/。
服务端发布包路径要和客户端 install_root 对应:
| 客户端配置 | 服务端 Manifest 路径口径 |
|---|---|
更新系统在根目录,install_root 是 . |
MainApp.exe、App/xxx.dll 相对 SimCAE/ |
更新系统在 bin/,install_root 是 .. |
bin/MainApp.exe、App/xxx.dll 相对 SimCAE/ |
当前管理后台“发布包”上传接口会使用上传文件名作为 artifactName,后端按安全文件名校验。当前稳定支持的是发布一个完整安装包或压缩包文件,或者把文件放在 install_root 根层级;还不是“自动解析压缩包并生成 App/bin 多文件 Manifest”的完整安装器。后续如果要让在线 Updater 直接把多个文件铺到 App/、bin/ 等子目录,需要在现有发布包页面和 Go 后端上继续增强安全相对路径或 Manifest 文件清单生成能力。
如果后续要支持“更新系统在 bin/,但只校验和更新 App/”这类更窄的安装根目录,需要在管理后台和 Go 后端增加对应配置项,让服务端生成 ../App 这类定制 install_root。当前服务端自动生成配置时只使用标准的 . 或 ..。
如果开启 verify_installed_on_start,客户端会扫描 install_root 下的 EXE 和 DLL。整包 Manifest 中 required=true 的核心文件必须存在且 SHA-256 匹配;required=false 的可选组件文件可以由 MaintenanceTool 管理,缺失时不会阻止启动。可选组件建议放在独立目录中,例如 plugins/dap/,不要和核心程序 DLL 混放。
上传完整客户软件 ZIP 时,服务端会根据发布包记录自动写入这些关键值:
{
"product_code": "stage2-dap",
"channel": "stable",
"current_version": "1.1.0",
"api_base_url": "http://192.168.1.158:18000",
"client_token": "<由服务器 .env 配置>",
"install_root": ". 或 ..",
"platform": "windows",
"arch": "x86_64",
"abi": "msvc"
}
install_root 由服务端根据 Launcher 所在位置自动判断:更新系统在软件根目录时写 .,在 bin/ 目录时写 ..。
7. 运行数据位置
Windows 运行数据目录:
%LOCALAPPDATA%\SimCAE\HubUpdateClient\installations\<安装目录SHA256>\
Linux 运行数据目录:
$XDG_DATA_HOME/SimCAE/HubUpdateClient/installations/<安装目录SHA256>/
未设置 XDG_DATA_HOME 时通常是:
~/.local/share/SimCAE/HubUpdateClient/installations/<安装目录SHA256>/
Manifest 缓存保存在运行数据目录下的 update/manifest_cache。
8. 常见问题
- 客户门户登录失败:检查客户门户账号是否已激活、客户是否生效、密码是否正确。
- 检查更新没有结果:检查后台发布是否已发布、发布包是否可用、产品编码、渠道和平台参数是否一致。
- 下载 401:检查发布包中的
config/app_config.json是否由服务端生成,client_token是否和服务器.env中的SIMCAE_CLIENT_TOKEN一致。 - Manifest 校验失败:检查服务端 Manifest 是否被篡改、发布包 SHA-256 是否和实际文件一致。
- 强制签名失败:确认
manifest_public_key.pem与服务端私钥匹配;如果服务端暂未启用签名,测试环境可先把require_manifest_signature设为false。 - 启动主程序失败:检查
main_executable和install_root是否指向真实文件。