AllStar2.0/状态机.md

556 lines
9.6 KiB
Markdown
Raw Normal View History

2026-04-27 14:23:41 +08:00
```markdown
# 状态机与 `device-bootstrap` 术语说明
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
## 一、核心结论
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
**状态机**:用于管理一次视频会话或设备流程的状态变化,明确规定当前处于什么状态、下一步能进入什么状态、异常时如何处理。
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
**`device-bootstrap`**:设备启动或上线时访问的接入服务,用于完成设备认证,并下发 MQTT 临时凭证、topic 权限、连接配置和设备能力配置。
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
---
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
## 二、状态机是什么意思
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
### 1. 通俗理解
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
状态机可以理解成一张**流程规则表**。
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
比如一次智能锁视频通话,不应该只有:
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
```text
开始通话
结束通话
```
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
而应该有完整流程:
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
```text
待创建 -> 呼叫中 -> 已接听 -> 连接中 -> 已连接 -> 已结束
```
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
每个状态只能按照规则进入下一个状态。
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
例如:
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
```text
pending -> ringing -> accepted -> connecting -> connected -> ended
```
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
不能随意跳转,例如:
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
```text
pending -> connected
```
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
通常是不合理的,因为中间还没有经过设备接听、媒体连接等步骤。
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
---
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
## 三、状态机在智能锁项目中的作用
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
旧方案里,可能通过 UDP 字段直接通知 APP 或锁:
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
```text
开始视频
结束视频
```
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
这种方式简单,但容易出现以下问题:
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
- APP 以为开始了,设备没收到
- 设备接听了APP 已经取消
- 网络抖动导致消息重复
- 云端不知道当前到底是“呼叫中”还是“已连接”
- 通话失败后不好追踪原因
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
新方案中,由 `session-orchestrator` 统一管理状态机。
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
也就是云端统一记录:
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
```text
这个 sessionId 当前到底处于什么状态
```
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
---
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
## 四、视频会话状态机示例
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
### 1. 推荐状态
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
| 状态 | 中文含义 |
|---|---|
| `pending` | 会话刚创建,等待发起呼叫 |
| `ringing` | 正在呼叫设备 / 设备响铃 |
| `accepted` | 设备已接听 |
| `connecting` | APP 和设备正在建立媒体连接 |
| `connected` | 音视频已连通 |
| `degraded` | 通话质量下降 |
| `switching_route` | 正在切换媒体线路 |
| `recovered` | 切换后恢复正常 |
| `ended` | 正常结束 |
| `rejected` | 被拒接 |
| `timeout` | 超时未响应 |
| `failed` | 异常失败 |
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
---
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
### 2. 正常通话流程
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
```text
2026-04-27 14:10:24 +08:00
pending
-> ringing
-> accepted
-> connecting
-> connected
-> ended
2026-04-27 14:23:41 +08:00
```
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
对应中文流程:
```text
2026-04-27 14:10:24 +08:00
创建会话
-> 呼叫设备
-> 设备接听
-> 建立 WebRTC / ZLM 连接
-> 通话成功
-> 挂断结束
2026-04-27 14:23:41 +08:00
```
---
### 3. 异常流程示例
#### 设备不在线
```text
2026-04-27 14:10:24 +08:00
pending -> failed
2026-04-27 14:23:41 +08:00
```
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
失败原因:
```text
2026-04-27 14:10:24 +08:00
device_offline
2026-04-27 14:23:41 +08:00
```
#### 设备没有响应
```text
2026-04-27 14:10:24 +08:00
pending -> ringing -> timeout
2026-04-27 14:23:41 +08:00
```
失败原因:
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
```text
2026-04-27 14:10:24 +08:00
invite_timeout
2026-04-27 14:23:41 +08:00
```
#### 用户取消
```text
2026-04-27 14:10:24 +08:00
pending -> ringing -> ended
2026-04-27 14:23:41 +08:00
```
结束原因:
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
```text
2026-04-27 14:10:24 +08:00
caller_cancelled
2026-04-27 14:23:41 +08:00
```
#### 设备拒接
```text
2026-04-27 14:10:24 +08:00
pending -> ringing -> rejected
2026-04-27 14:23:41 +08:00
```
失败原因:
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
```text
2026-04-27 14:10:24 +08:00
device_rejected
2026-04-27 14:23:41 +08:00
```
#### WebRTC 连接失败后切换 ZLMediaKit
```text
2026-04-27 14:10:24 +08:00
pending
-> ringing
-> accepted
-> connecting
-> degraded
-> switching_route
-> recovered
-> connected
2026-04-27 14:23:41 +08:00
```
---
## 五、为什么需要状态机
### 1. 保证流程不乱
2026-04-27 14:10:24 +08:00
没有状态机时,可能出现:
2026-04-27 14:23:41 +08:00
```text
2026-04-27 14:10:24 +08:00
已经挂断了,又收到设备 accept
2026-04-27 14:23:41 +08:00
```
2026-04-27 14:10:24 +08:00
有状态机后可以规定:
2026-04-27 14:23:41 +08:00
```text
2026-04-27 14:10:24 +08:00
ended 状态下收到 accept直接忽略或记录为迟到事件
2026-04-27 14:23:41 +08:00
```
---
### 2. 方便排查问题
有状态机后,可以按 `sessionId` 查完整流程:
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
```text
2026-04-27 14:10:24 +08:00
sessionId = abc123
pending at 10:00:01
ringing at 10:00:02
accepted at 10:00:05
connecting at 10:00:06
timeout at 10:00:16
reason = ice_timeout
2026-04-27 14:23:41 +08:00
```
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
这样可以明确知道失败原因是:
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
```text
设备接听了,但 WebRTC 没连上
```
而不是笼统地显示:
```text
2026-04-27 14:10:24 +08:00
通话失败
2026-04-27 14:23:41 +08:00
```
---
### 3. 方便做超时和重试
状态机可以支持:
- 呼叫设备 15 秒没响应,自动超时
- WebRTC 10 秒没连上,切换 ZLMediaKit
- 设备 ACK 没回来,重发 invite
- 通话结束后清理 token 和流媒体资源
---
## 六、`device-bootstrap` 是什么意思
### 1. 通俗理解
`device-bootstrap` 可以理解为:
> 设备上线入口 / 设备启动接入服务 / 设备报到服务
设备开机后,不应该直接随便连接 MQTT也不应该把固定账号密码写死在固件里。
更安全的做法是:
```text
设备开机
-> 调用 device-bootstrap
-> 云端验证设备身份
-> 云端返回 MQTT 地址、临时账号、topic 权限、配置
-> 设备再连接 BifroMQ
```
---
## 七、`device-bootstrap` 在项目中的作用
### 1. 设备启动时的流程
设备,也就是 WiFi 网关锁,启动后先请求:
```http
POST /device/bootstrap
```
请求中通常携带:
```json
{
"deviceId": "device_001",
"firmwareVersion": "1.0.0",
"timestamp": 1710000000,
"signature": "xxxxx",
"capabilities": {
"webrtc": true,
"zlm": true,
"ai": true
}
}
```
云端验证通过后返回:
```json
{
"mqtt": {
"host": "mqtt.example.com",
"port": 8883,
"clientId": "lock_xxx",
"username": "tmp_user",
"password": "tmp_password",
"expiresIn": 3600
},
"topics": {
"subscribe": [
"tenant/t1/device/d1/control",
"tenant/t1/session/+/signal/device"
],
"publish": [
"tenant/t1/device/d1/status",
"tenant/t1/device/d1/event",
"tenant/t1/session/+/signal/app"
]
},
"config": {
"heartbeatInterval": 30,
"webrtcEnabled": true,
"zlmEnabled": true,
"aiEnabled": true
}
}
```
含义是:
- 设备认证通过
- 返回 MQTT 连接地址
- 返回临时账号密码
- 返回允许订阅的 topic
- 返回允许发布的 topic
- 返回心跳周期
- 返回设备功能开关配置
---
## 八、`device-bootstrap` 解决的问题
### 1. 避免设备写死 MQTT 密码
不推荐:
```text
所有设备固件里写同一个 MQTT 用户名和密码
```
风险是:一旦泄露,所有设备都会受影响。
推荐:
```text
每台设备启动时领取自己的临时凭证
```
---
### 2. 控制设备权限
例如设备 `device_001` 只能访问:
```text
tenant/t1/device/device_001/...
```
不能访问:
```text
tenant/t1/device/device_002/...
```
---
### 3. 支持设备配置下发
例如某个设备支持 WebRTC
```json
{
"webrtcEnabled": true
}
```
另一个旧设备不支持:
```json
{
"webrtcEnabled": false
}
```
系统就可以按设备能力下发不同策略。
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
---
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
### 4. 支持灰度升级
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
例如只让 10% 的设备启用 ZLMediaKit
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
```json
{
"zlmEnabled": true
}
```
2026-04-27 14:10:24 +08:00
2026-04-27 14:23:41 +08:00
其它设备暂时不开启。
---
## 九、`device-bootstrap` 和 `session-orchestrator` 的区别
| 模块 | 作用 | 类比 |
|---|---|---|
| `device-bootstrap` | 设备上线认证、领取 MQTT 凭证、获取配置 | 门卫 / 报到处 |
| `session-orchestrator` | 管理一次视频会话的创建、呼叫、接听、连接、切路、挂断 | 调度员 / 指挥中心 |
| BifroMQ | 负责消息通道 | 对讲机频道 / 消息总线 |
| ZLMediaKit / WebRTC | 负责音视频传输 | 真正的视频通话线路 |
简单理解:
```text
device-bootstrap 管设备怎么接入系统
session-orchestrator 管一次通话怎么开始、进行、结束
```
---
## 十、完整流程<E6B581><E7A88B><EFBFBD>
### 1. 设备上线流程
```text
WiFi锁开机
-> 调用 device-bootstrap
-> bootstrap 验证设备身份
-> 返回 MQTT 临时凭证
-> WiFi锁连接 BifroMQ
-> WiFi锁上报 online
```
这部分由 `device-bootstrap` 负责。
---
### 2. 用户发起视频通话流程
```text
APP 点击视频通话
-> 调用 starlock
-> starlock 校验用户是否有权限访问这把锁
-> starlock 调用 session-orchestrator 创建 session
-> session-orchestrator 通过 BifroMQ 给设备发 invite
-> 设备响铃并返回 accept
-> APP 和设备交换 WebRTC signaling
-> 建立 P2P / TURN / ZLM 媒体链路
```
这部分由 `session-orchestrator` 负责。
---
### 3. 通话中弱网切换流程
```text
APP 上报丢包高
设备上报 RTT 高
session-orchestrator 判断质量差
-> 下发 switch-route
-> APP 和设备切到 ZLMediaKit
```
这仍然属于状态机控制。
---
## 十一、<E4B880><E38081><EFBFBD>团队的简短解释
### 状态机一句话
> 状态机就是云端统一管理“这次通话现在进行到哪一步、下一步允许做什么、超时或异常怎么处理”的规则系统。
### `device-bootstrap` 一句话
> `device-bootstrap` 就是设备开机后的接入报到服务,负责认证设备,并给设备下发 MQTT 临时凭证、topic 权限和能力配置。
---
## 十二、项目落地建议
### 1. 状态机第一版建议
第一版状态不要太复杂,建议先支持:
```text
created
ringing
accepted
connecting
connected
ended
rejected
timeout
failed
```
后续稳定后再增加:
```text
degraded
switching_route
recovered
```
---
### 2. `device-bootstrap` 第一版必须返回
```text
mqttHost
mqttPort
clientId
username
password
expiresIn
subscribeTopics
publishTopics
heartbeatInterval
capabilities
```
不要让设备直接写死 MQTT 账号密码。
---
## 十三、最简对照表
| 模块 | 负责内容 |
|---|---|
| 状态机 | 管“通话流程” |
| `device-bootstrap` | 管“设备上线接入” |
| BifroMQ | 管“消息通道” |
| WebRTC / ZLM | 管“视频声音怎么传” |
| `starlock` | 管“用户有没有权限” |
| `starcloud` | 管“共享业务能力” |
---
## 十四、总结
在智能锁实时系统中:
```text
用户有没有权限开视频starlock / starcloud 判断
设备怎么连上云device-bootstrap
控制消息怎么传BifroMQ
这次通话现在到哪一步session-orchestrator 状态机
视频音频怎么传WebRTC / TURN / ZLMediaKit
```
```