AllStar2.0/状态机.md
2026-04-27 14:10:24 +08:00

205 lines
3.5 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.

状态机就是“把一次视频会话/设备流程拆成明确状态,并规定状态之间怎么流转”的机制。
device-bootstrap 就是“设备启动或上线时,先来云端报到、认证,并领取连接 MQTT/实时系统所需临时配置和凭证”的接入服务。
1. 状态机是什么意思
1.1 通俗解释
状态机可以理解成一张流程规则表。
比如一次智能锁视频通话,不应该只是简单地说:
开始通话
结束通话
而是应该有一系列明确状态:
待创建 -> 呼叫中 -> 已接听 -> 连接中 -> 已连接 -> 通话中 -> 已结束
每个状态只能按照规则进入下一个状态。
例如:
pending -> ringing -> accepted -> connecting -> connected -> ended
不能乱跳,比如:
pending -> connected
通常就不合理,因为中间还没经过设备接听和媒体连接。
1.2 在你这个智能锁项目里的含义
你们旧方案里可能是通过 UDP 字段告诉 APP 或锁:
开始视频
结束视频
这种方式简单,但问题是:
APP 以为开始了,设备没收到
设备接听了APP 已经取消
网络抖动导致消息重复
云端不知道现在到底是“呼叫中”还是“已连接”
通话失败后不好追踪原因
所以新方案里要用 session-orchestrator 管理状态机。
也就是云端统一记录:
这个 sessionId 当前到底处于什么状态
2. 视频会话状态机例子
2.1 推荐状态
pending
ringing
accepted
connecting
connected
degraded
switching_route
recovered
ended
rejected
timeout
failed
可以翻译成:
状态
中文含义
pending
会话刚创建,等待发起呼叫
ringing
正在呼叫设备 / 设备响铃
accepted
设备已接听
connecting
APP 和设备正在建立媒体连接
connected
音视频已连通
degraded
通话质量下降
switching_route
正在切换媒体线路
recovered
切换后恢复正常
ended
正常结束
rejected
被拒接
timeout
超时未响应
failed
异常失败
2.2 状态流转例子
一次正常视频通话:
pending
-> ringing
-> accepted
-> connecting
-> connected
-> ended
中文就是:
创建会话
-> 呼叫设备
-> 设备接听
-> 建立 WebRTC / ZLM 连接
-> 通话成功
-> 挂断结束
2.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
-> failed_p2p
-> switching_route
-> connected
或者更规范一点:
connecting
-> degraded
-> switching_route
-> recovered
-> connected
3. 为什么一定要状态机
3.1 保证流程不乱
没有状态机时,可能出现:
已经挂断了,又收到设备 accept
那系统不知道该怎么办。
有状态机后可以规定:
ended 状态下收到 accept直接忽略或记录为迟到事件
3.2 方便排查问题
有状态机后,每个会话都能查:
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.3 方便做超时和重试
比如:
呼叫设备 15 秒没响应,自动超时
WebRTC 10 秒没连上,切 ZLM
设备 ACK 没回来,重发 invite
通话结束后清理 token 和流资源
这些都依赖状态机。