213 lines
7.3 KiB
Markdown
213 lines
7.3 KiB
Markdown
# N7Cockpit 跨服务器迁移与联调手册
|
||
|
||
## 1. 部署拓扑
|
||
|
||
本工程采用统一服务端事件链路,不做网页自动点击:
|
||
|
||
```text
|
||
Android / N7Cockpit
|
||
| HTTPS/HTTP + Bearer token
|
||
| mode_id / execution_id / event sequence
|
||
v
|
||
服务器 A:Cognitive_Agent :8000
|
||
| 展开服务器预设模式、安全校验、执行与状态回读
|
||
+--> Web 控制台(同一事件流)
|
||
+--> CAN 盒与车端设备(仅 hardware + 本地批准时)
|
||
|
||
服务器 B:保存 N7Cockpit 源码、构建 APK、通过 ADB 安装到 Android
|
||
```
|
||
|
||
`127.0.0.1:8000` 只表示“当前机器”。Android 设备访问服务器 A 时必须使用
|
||
服务器 A 的可路由 IP 或 DNS 名。只有 Android Emulator 与服务器 A 同机时,APK
|
||
中的服务器 A 地址才使用 `http://10.0.2.2:8000`。
|
||
|
||
## 2. 服务器 A:启动 Cognitive_Agent
|
||
|
||
服务器 A 必须已经包含本项目配套修改后的 Cognitive_Agent。进入其工程目录,生成
|
||
至少 32 字符的随机设备令牌;令牌只在服务器 A 和服务器 B 的私密文件中保存:
|
||
|
||
```powershell
|
||
cd D:\path\to\Cognitive_Agent
|
||
$tokenBytes = New-Object byte[] 48
|
||
$rng = [Security.Cryptography.RandomNumberGenerator]::Create()
|
||
try { $rng.GetBytes($tokenBytes) } finally { $rng.Dispose() }
|
||
$deviceToken = [Convert]::ToBase64String($tokenBytes)
|
||
$deviceToken | Set-Content -NoNewline .\n7-device-token.txt
|
||
```
|
||
|
||
启动服务。当前 PowerShell 会话关闭后进程也会终止,生产环境应再配置 Windows
|
||
Service、NSSM 或反向代理进程守护:
|
||
|
||
```powershell
|
||
$env:PYTHONPATH = 'src'
|
||
$env:COGNITIVE_AGENT_DEVICE_API_TOKEN = (
|
||
Get-Content .\n7-device-token.txt -Raw
|
||
).Trim()
|
||
python -m cognitive_agent.server --host 0.0.0.0 --port 8000
|
||
```
|
||
|
||
服务器 A 防火墙只允许服务器 B、Android 车机和 Web 管理端访问 TCP 8000。生产
|
||
环境必须在服务器前配置 HTTPS;HTTP 仅适用于受信任的隔离局域网。
|
||
|
||
从服务器 B 检查网络。这里不能使用服务器 B 的 `127.0.0.1`:
|
||
|
||
```powershell
|
||
Test-NetConnection 192.168.1.10 -Port 8000
|
||
```
|
||
|
||
Web 控制台地址也应改为服务器 A 地址:`http://192.168.1.10:8000/`。服务器 A
|
||
本机访问时才使用 `http://127.0.0.1:8000/`。
|
||
|
||
## 3. 服务器 B:解压和初始化
|
||
|
||
安装以下依赖:
|
||
|
||
- Windows PowerShell 5.1 或 PowerShell 7;
|
||
- JDK 17 或更高版本;
|
||
- Android SDK Platform 35 和 Platform Tools;
|
||
- 首次构建可访问 Gradle/Google/Aliyun Maven 仓库。
|
||
|
||
解压 ZIP 后:
|
||
|
||
```powershell
|
||
cd D:\Deploy\N7Cockpit
|
||
powershell -NoProfile -ExecutionPolicy Bypass `
|
||
-File .\scripts\initialize-migration.ps1
|
||
```
|
||
|
||
编辑 `config\migration.psd1`:
|
||
|
||
```powershell
|
||
@{
|
||
ServerAUrl = 'http://192.168.1.10:8000'
|
||
AndroidServerAUrl = 'http://192.168.1.10:8000'
|
||
VehicleId = 'denza_n7'
|
||
HardwareClientId = 'hwc-n7cockpit-server-b-001'
|
||
ExecutionTarget = 'dry_run'
|
||
TokenFile = 'secrets/device-token.txt'
|
||
JavaHome = 'C:\Program Files\Android\Android Studio\jbr'
|
||
AndroidSdk = 'C:\Users\Administrator\AppData\Local\Android\Sdk'
|
||
GradleExecutable = ''
|
||
}
|
||
```
|
||
|
||
把服务器 A 的 `n7-device-token.txt` 安全复制到服务器 B 的
|
||
`secrets\device-token.txt`。不要通过聊天、代码仓库或普通邮件传输。配置和 secrets
|
||
目录均被打包规则排除。
|
||
|
||
先验证环境及服务器 A:
|
||
|
||
```powershell
|
||
powershell -NoProfile -ExecutionPolicy Bypass `
|
||
-File .\scripts\verify-migration-environment.ps1
|
||
powershell -NoProfile -ExecutionPolicy Bypass `
|
||
-File .\scripts\check-server-a.ps1
|
||
```
|
||
|
||
两条命令都应返回 `Passed=True`,且 `PresetModes` 大于 0。
|
||
|
||
## 4. 构建和安装 Android APK
|
||
|
||
安全联调构建:
|
||
|
||
```powershell
|
||
powershell -NoProfile -ExecutionPolicy Bypass `
|
||
-File .\scripts\build-migrated-apk.ps1 -Variant debug
|
||
```
|
||
|
||
脚本会先验证服务器 A、运行 Android 单元测试,再生成:
|
||
|
||
```text
|
||
dist\N7Cockpit-remote-debug.apk
|
||
dist\build-info.json
|
||
```
|
||
|
||
`GradleExecutable` 留空时使用包内 Gradle Wrapper;首次构建会下载 Gradle 8.9。
|
||
服务器若已安装 Gradle 8.9,可填写 `gradle.bat` 的绝对路径以避免重复下载。
|
||
|
||
设备开启开发者选项和 USB 调试,执行:
|
||
|
||
```powershell
|
||
adb devices
|
||
powershell -NoProfile -ExecutionPolicy Bypass `
|
||
-File .\scripts\install-migrated-apk.ps1 -Variant debug
|
||
```
|
||
|
||
如有多个设备,增加 `-Serial <adb序列号>`。远程调试包名为
|
||
`com.seeker.n7cockpit.remote`,可与正式包共存。
|
||
|
||
## 5. dry_run 联调验收
|
||
|
||
先进行不会访问 CAN 的服务器 A 冒烟测试:
|
||
|
||
```powershell
|
||
powershell -NoProfile -ExecutionPolicy Bypass `
|
||
-File .\scripts\test-server-a-dry-run.ps1
|
||
```
|
||
|
||
必须看到:
|
||
|
||
- `Passed=True`;
|
||
- `CanExecuted=False`;
|
||
- `ExecutionTarget=dry_run`;
|
||
- `Status=succeeded`。
|
||
|
||
然后打开 Android 的“模式”页:
|
||
|
||
1. 顶部应显示服务器 A URL 和“编排服务已连接”;
|
||
2. 应加载宝宝午睡、零重力、小憩、轻松进出等服务器预设模式;
|
||
3. 点击“宝宝午睡模式”;
|
||
4. Android 显示 `queued/executing/succeeded`、execution_id 和车端模拟状态;
|
||
5. 打开服务器 A 的 Web 控制台,显示同一模式、`source:N7Cockpit`、同一
|
||
execution_id 和同步后的数字孪生状态。
|
||
|
||
此阶段不要点击“申请真实硬件控制”。
|
||
|
||
## 6. 实体 Android 与模拟器的地址选择
|
||
|
||
| 场景 | AndroidServerAUrl |
|
||
|---|---|
|
||
| 模拟器与服务器 A 同机 | `http://10.0.2.2:8000` |
|
||
| 模拟器在服务器 B,服务器 A 独立 | 服务器 A 的 LAN IP/DNS |
|
||
| 实体 Android/车机 | 服务器 A 的 LAN IP/DNS |
|
||
| 生产环境 | 服务器 A 的 HTTPS 域名 |
|
||
|
||
服务器 B 的 `ServerAUrl` 始终填写服务器 B 能访问的服务器 A 地址。
|
||
|
||
## 7. 切换真实 CAN(完成 dry_run 后单独进行)
|
||
|
||
真实硬件不属于默认迁移验收范围。确认急停、机械限位、CAN 通道和车端供电安全后:
|
||
|
||
1. 将配置改为 `ExecutionTarget='hardware'`;
|
||
2. 显式构建:
|
||
|
||
```powershell
|
||
powershell -NoProfile -ExecutionPolicy Bypass `
|
||
-File .\scripts\build-migrated-apk.ps1 -Variant release -AllowHardware
|
||
```
|
||
|
||
3. Android 点击“申请真实硬件控制”;
|
||
4. 只能在服务器 A 本机打开 `/hardware-control` 批准对应 HardwareClientId;
|
||
5. 批准后才允许 hardware 任务进入 CAN 执行。
|
||
|
||
`-AllowHardware` 和服务器 A 本地批准是两层独立安全门,远程设备令牌不能自批准。
|
||
|
||
## 8. 常见故障
|
||
|
||
- `401`:服务器 A 与 APK 使用的设备令牌不一致,或服务重启时没有加载令牌。
|
||
- `Connection refused/timed out`:服务未监听 `0.0.0.0`、防火墙未放行,或 URL
|
||
错填为 Android/服务器 B 自己的 `127.0.0.1`。
|
||
- 模式为空:车型 ID 不匹配,或服务器 A 不是包含预设模式 API 的配套版本。
|
||
- Android 可访问但 Web 不更新:Web 未登录,或浏览器标签长期后台导致轮询暂停;
|
||
激活页面后会继续读取新事件。
|
||
- Gradle 下载失败:检查代理/DNS;工程已同时配置 Aliyun 与官方仓库。
|
||
- SDK XML 警告:Android Studio 与 command-line tools 版本差异警告,若构建最终
|
||
`BUILD SUCCESSFUL` 通常不影响 APK。
|
||
|
||
## 9. 安全说明
|
||
|
||
设备令牌会进入 APK BuildConfig。只应把 APK 安装到受控车机;如果 APK 可能公开
|
||
分发,应改为设备注册和短期凭据。令牌泄露后必须在服务器 A 生成新令牌、重启服务
|
||
并重新构建 APK。ZIP 源码包不会包含设备令牌、构建目录、历史 APK、测试截图或
|
||
本机 Gradle 缓存。
|