Files
cmr-mini/doc/archive/notes/多人模拟器待办.md

337 lines
6.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 多人模拟器改造待开发文档
> 文档版本v1.0
> 最后更新2026-04-02 08:28:05
本文档用于记录“公网模拟器支持多人开发/多人联调”的待开发方案。
当前仅作为设计与排期参考,不代表已经进入实现阶段。
---
## 1. 目标
当前外部模拟器已经支持:
- mock GPS
- mock heart rate
- 公网 WebSocket 接入
但当前模型更接近“单会话广播”。
如果多人同时开发或联调,容易出现:
- A 的 GPS 影响 B 的小程序
- C 的心率影响 D 的 HUD
- 同一公网模拟器服务缺乏隔离能力
因此需要把模拟器体系升级成:
- 多房间
- 多身份
- 按目标订阅
最终目标是:
- 多人共用同一个公网模拟服务
- 各自的数据流互不干扰
- 为未来多人玩法联调留好底座
---
## 2. 当前问题本质
当前模拟器通信模型更像:
- 一个 WebSocket 服务
- 模拟器侧发布消息
- 小程序侧直接接收
这个模型在单人开发时足够。
但在多人开发时,缺少以下维度:
- `room`
- `actorId`
- `channel`
没有这些维度时,服务端无法做消息隔离与路由控制。
---
## 3. 建议的第一阶段方案
第一阶段不追求复杂功能,只解决“多人不串流”的核心问题。
### 3.1 核心模型
为所有模拟消息增加 3 个维度:
- `room`
- `actorId`
- `channel`
含义如下:
- `room`
表示一个独立测试空间
- `actorId`
表示房间中的一个具体模拟源
- `channel`
表示消息类型,例如 `gps``heart_rate`
### 3.2 第一阶段目标
第一阶段完成后应满足:
- A 和 B 可以共用同一个公网模拟器服务
- A 的小程序只接 A 的数据
- B 的小程序只接 B 的数据
- GPS 与心率都能隔离
---
## 4. 推荐协议
### 4.1 模拟器注册
```json
{
"type": "register_simulator",
"room": "team-dev",
"actorId": "sim-a"
}
```
### 4.2 小程序订阅
```json
{
"type": "subscribe",
"room": "team-dev",
"actorId": "sim-a",
"channels": ["gps", "heart_rate"]
}
```
### 4.3 发布 GPS
```json
{
"type": "publish",
"room": "team-dev",
"actorId": "sim-a",
"channel": "gps",
"payload": {
"type": "mock_gps",
"timestamp": 1711267200000,
"lat": 31.2304,
"lon": 121.4737,
"accuracyMeters": 6,
"speedMps": 2.4,
"headingDeg": 135
}
}
```
### 4.4 发布心率
```json
{
"type": "publish",
"room": "team-dev",
"actorId": "sim-a",
"channel": "heart_rate",
"payload": {
"type": "mock_heart_rate",
"timestamp": 1711267200000,
"bpm": 148
}
}
```
---
## 5. 服务端改造建议
### 5.1 服务端职责
服务端从“直接广播”升级成“按订阅路由”。
它需要维护每个 WebSocket 连接的元数据:
```ts
type ClientSession = {
socketId: string
role: 'simulator' | 'app'
room: string | null
actorId: string | null
channels: Set<string>
}
```
### 5.2 路由规则
服务端收到 `publish` 后,只转发给满足以下条件的客户端:
- `role === 'app'`
- `room` 一致
- `actorId` 一致
- `channels` 包含当前 `channel`
这一步完成后,多人使用同一个公网服务时就不会互串。
### 5.3 第一阶段不需要的复杂能力
第一阶段不建议先做:
- 房间成员列表
- 在线人数统计
- 历史消息回放
- 房间消息缓存
- 权限控制
这些可以等基础隔离跑通后再扩。
---
## 6. 小程序侧改造建议
### 6.1 调试面板新增字段
建议在调试面板中新增:
- `Mock Room`
- `Mock Actor`
- `保存房间/身份`
当前 GPS 和心率已经都有 mock bridge后续建议最终共用同一个逻辑目标
- 同一个桥接地址
- 同一个 `room`
- 同一个 `actorId`
### 6.2 连接流程
小程序连上 mock bridge 后,自动发送:
```json
{
"type": "subscribe",
"room": "...",
"actorId": "...",
"channels": ["gps", "heart_rate"]
}
```
这样:
- GPS 模拟只接自己的 `gps`
- 心率模拟只接自己的 `heart_rate`
### 6.3 当前架构适配性
这项改造与当前架构是兼容的。
原因:
- 它主要发生在传感层和调试链
- 不需要改规则层
- 不需要改 telemetry 语义
- 不需要改地图引擎主逻辑
---
## 7. 外部模拟器改造建议
### 7.1 第一阶段 UI 最小改动
模拟器左侧面板新增两个输入项:
- `Room`
- `Actor ID`
后续所有 GPS / 心率发送都自动带上它们。
### 7.2 推荐默认使用方式
多人开发时建议:
- 大家共用同一个公网服务地址
- `room` 用项目或阶段名
- `actorId` 用开发者自己名字或实例名
示例:
- room: `team-dev`
- actorId: `zhangsan`
- actorId: `lisi`
### 7.3 后续可扩展能力
后续如果要继续增强,可以加:
- 房间成员列表
- 一键复制当前房间配置
- 旁观模式
- 同房间多个 actor 同时显示
- 共享路径模板
---
## 8. 为什么这项改造值得做
这不只是为了多人开发方便。
它还会直接为未来这些方向打基础:
- 多人玩法联调
- 团队对抗玩法
- 领地争夺玩法
- 多角色追逐玩法
也就是说:
今天为“多人模拟器”加的 `room + actorId + channel`,未来可以直接演进成多人玩法调试底座。
---
## 9. 建议实施顺序
### 第一阶段
- 服务端支持 `register_simulator / subscribe / publish`
- 消息带 `room + actorId + channel`
- 小程序支持订阅指定 `room + actorId`
- 外部模拟器增加 `room / actorId`
### 第二阶段
- 增加房间成员列表
- 增加在线状态
- 增加多 actor 可视化
### 第三阶段
- 接多人玩法联调
- 接角色维度
- 接会话回放与共享调试
---
## 10. 第一阶段验收标准
第一阶段完成后,至少应满足:
1. 两个人同时连同一个公网模拟器服务,不串 GPS
2. 两个人同时连同一个公网模拟器服务,不串心率
3. 同一个房间中,不同 `actorId` 可以隔离
4. 一个小程序实例可以只接收自己配置的目标流
---
## 11. 当前结论
这项改造建议先保留为待开发事项。
当前阶段不急着实现,但应作为后续多人开发与多人玩法联调的重要底座能力。