AllStar2.0/术语:状态机.md

9.6 KiB
Raw Permalink Blame History

# 状态机与 `device-bootstrap` 术语说明

## 一、核心结论

**状态机**:用于管理一次视频会话或设备流程的状态变化,明确规定当前处于什么状态、下一步能进入什么状态、异常时如何处理。

**`device-bootstrap`**:设备启动或上线时访问的接入服务,用于完成设备认证,并下发 MQTT 临时凭证、topic 权限、连接配置和设备能力配置。

---

## 二、状态机是什么意思

### 1. 通俗理解

状态机可以理解成一张**流程规则表**。

比如一次智能锁视频通话,不应该只有:

```text
开始通话
结束通话

而应该有完整流程:

待创建 -> 呼叫中 -> 已接听 -> 连接中 -> 已连接 -> 已结束

每个状态只能按照规则进入下一个状态。

例如:

pending -> ringing -> accepted -> connecting -> connected -> ended

不能随意跳转,例如:

pending -> connected

通常是不合理的,因为中间还没有经过设备接听、媒体连接等步骤。


三、状态机在智能锁项目中的作用

旧方案里,可能通过 UDP 字段直接通知 APP 或锁:

开始视频
结束视频

这种方式简单,但容易出现以下问题:

  • APP 以为开始了,设备没收到
  • 设备接听了APP 已经取消
  • 网络抖动导致消息重复
  • 云端不知道当前到底是“呼叫中”还是“已连接”
  • 通话失败后不好追踪原因

新方案中,由 session-orchestrator 统一管理状态机。

也就是云端统一记录:

这个 sessionId 当前到底处于什么状态

四、视频会话状态机示例

1. 推荐状态

状态 中文含义
pending 会话刚创建,等待发起呼叫
ringing 正在呼叫设备 / 设备响铃
accepted 设备已接听
connecting APP 和设备正在建立媒体连接
connected 音视频已连通
degraded 通话质量下降
switching_route 正在切换媒体线路
recovered 切换后恢复正常
ended 正常结束
rejected 被拒接
timeout 超时未响应
failed 异常失败

2. 正常通话流程

pending
  -> ringing
  -> accepted
  -> connecting
  -> connected
  -> ended

对应中文流程:

创建会话
  -> 呼叫设备
  -> 设备接听
  -> 建立 WebRTC / ZLM 连接
  -> 通话成功
  -> 挂断结束

3. 异常流程示例

设备不在线

pending -> failed

失败原因:

device_offline

设备没有响应

pending -> ringing -> timeout

失败原因:

invite_timeout

用户取消

pending -> ringing -> ended

结束原因:

caller_cancelled

设备拒接

pending -> ringing -> rejected

失败原因:

device_rejected

WebRTC 连接失败后切换 ZLMediaKit

pending
  -> ringing
  -> accepted
  -> connecting
  -> degraded
  -> switching_route
  -> recovered
  -> connected

五、为什么需要状态机

1. 保证流程不乱

没有状态机时,可能出现:

已经挂断了,又收到设备 accept

有状态机后可以规定:

ended 状态下收到 accept直接忽略或记录为迟到事件

2. 方便排查问题

有状态机后,可以按 sessionId 查完整流程:

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

这样可以明确知道失败原因是:

设备接听了,但 WebRTC 没连上

而不是笼统地显示:

通话失败

3. 方便做超时和重试

状态机可以支持:

  • 呼叫设备 15 秒没响应,自动超时
  • WebRTC 10 秒没连上,切换 ZLMediaKit
  • 设备 ACK 没回来,重发 invite
  • 通话结束后清理 token 和流媒体资源

六、device-bootstrap 是什么意思

1. 通俗理解

device-bootstrap 可以理解为:

设备上线入口 / 设备启动接入服务 / 设备报到服务

设备开机后,不应该直接随便连接 MQTT也不应该把固定账号密码写死在固件里。

更安全的做法是:

设备开机
  -> 调用 device-bootstrap
  -> 云端验证设备身份
  -> 云端返回 MQTT 地址、临时账号、topic 权限、配置
  -> 设备再连接 BifroMQ

七、device-bootstrap 在项目中的作用

1. 设备启动时的流程

设备,也就是 WiFi 网关锁,启动后先请求:

POST /device/bootstrap

请求中通常携带:

{
  "deviceId": "device_001",
  "firmwareVersion": "1.0.0",
  "timestamp": 1710000000,
  "signature": "xxxxx",
  "capabilities": {
    "webrtc": true,
    "zlm": true,
    "ai": true
  }
}

云端验证通过后返回:

{
  "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 密码

不推荐:

所有设备固件里写同一个 MQTT 用户名和密码

风险是:一旦泄露,所有设备都会受影响。

推荐:

每台设备启动时领取自己的临时凭证

2. 控制设备权限

例如设备 device_001 只能访问:

tenant/t1/device/device_001/...

不能访问:

tenant/t1/device/device_002/...

3. 支持设备配置下发

例如某个设备支持 WebRTC

{
  "webrtcEnabled": true
}

另一个旧设备不支持:

{
  "webrtcEnabled": false
}

系统就可以按设备能力下发不同策略。


4. 支持灰度升级

例如只让 10% 的设备启用 ZLMediaKit

{
  "zlmEnabled": true
}

其它设备暂时不开启。


九、device-bootstrapsession-orchestrator 的区别

模块 作用 类比
device-bootstrap 设备上线认证、领取 MQTT 凭证、获取配置 门卫 / 报到处
session-orchestrator 管理一次视频会话的创建、呼叫、接听、连接、切路、挂断 调度员 / 指挥中心
BifroMQ 负责消息通道 对讲机频道 / 消息总线
ZLMediaKit / WebRTC 负责音视频传输 真正的视频通话线路

简单理解:

device-bootstrap 管设备怎么接入系统
session-orchestrator 管一次通话怎么开始、进行、结束

十、完整流程<EFBFBD><EFBFBD><EFBFBD>

1. 设备上线流程

WiFi锁开机
  -> 调用 device-bootstrap
  -> bootstrap 验证设备身份
  -> 返回 MQTT 临时凭证
  -> WiFi锁连接 BifroMQ
  -> WiFi锁上报 online

这部分由 device-bootstrap 负责。


2. 用户发起视频通话流程

APP 点击视频通话
  -> 调用 starlock
  -> starlock 校验用户是否有权限访问这把锁
  -> starlock 调用 session-orchestrator 创建 session
  -> session-orchestrator 通过 BifroMQ 给设备发 invite
  -> 设备响铃并返回 accept
  -> APP 和设备交换 WebRTC signaling
  -> 建立 P2P / TURN / ZLM 媒体链路

这部分由 session-orchestrator 负责。


3. 通话中弱网切换流程

APP 上报丢包高
设备上报 RTT 高
session-orchestrator 判断质量差
  -> 下发 switch-route
  -> APP 和设备切到 ZLMediaKit

这仍然属于状态机控制。


十一、<EFBFBD><EFBFBD><EFBFBD>团队的简短解释

状态机一句话

状态机就是云端统一管理“这次通话现在进行到哪一步、下一步允许做什么、超时或异常怎么处理”的规则系统。

device-bootstrap 一句话

device-bootstrap 就是设备开机后的接入报到服务,负责认证设备,并给设备下发 MQTT 临时凭证、topic 权限和能力配置。


十二、项目落地建议

1. 状态机第一版建议

第一版状态不要太复杂,建议先支持:

created
ringing
accepted
connecting
connected
ended
rejected
timeout
failed

后续稳定后再增加:

degraded
switching_route
recovered

2. device-bootstrap 第一版必须返回

mqttHost
mqttPort
clientId
username
password
expiresIn
subscribeTopics
publishTopics
heartbeatInterval
capabilities

不要让设备直接写死 MQTT 账号密码。


十三、最简对照表

模块 负责内容
状态机 管“通话流程”
device-bootstrap 管“设备上线接入”
BifroMQ 管“消息通道”
WebRTC / ZLM 管“视频声音怎么传”
starlock 管“用户有没有权限”
starcloud 管“共享业务能力”

十四、总结

在智能锁实时系统中:

用户有没有权限开视频starlock / starcloud 判断
设备怎么连上云device-bootstrap
控制消息怎么传BifroMQ
这次通话现在到哪一步session-orchestrator 状态机
视频音频怎么传WebRTC / TURN / ZLMediaKit