2026-04-27 14:56:30 +08:00
|
|
|
|
下面这份是**基于你提供的“智能锁新实时系统方案”整理的模块开发周期、技术栈、难点和注意事项**。
|
2026-04-27 14:42:20 +08:00
|
|
|
|
|
2026-04-27 14:46:21 +08:00
|
|
|
|
> 预估前提:
|
2026-04-27 14:42:20 +08:00
|
|
|
|
> - `starcloud`、`starlock`、`app-starlock`、现有设备端已有基础能力。
|
|
|
|
|
|
> - 新项目重点是实时控制面、BifroMQ、WebRTC/TURN/ZLMediaKit、事件链路、AI 旁路。
|
|
|
|
|
|
> - 团队配置按:后端 2 人、APP 1 人、设备端 1 人、运维 1 人、测试 1 人估算。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
# 一、整体开发阶段建议
|
|
|
|
|
|
|
|
|
|
|
|
## 阶段划分
|
|
|
|
|
|
|
|
|
|
|
|
| 阶段 | 目标 | 周期预估 |
|
|
|
|
|
|
|---|---|---|
|
|
|
|
|
|
| 阶段 0:方案细化与协议设计 | 确定 topic、状态机、API、媒体选路策略 | 1 - 2 周 |
|
|
|
|
|
|
| 阶段 1:实时控制面 MVP | 完成 `session-orchestrator`、`device-bootstrap`、BifroMQ 基础接入 | 3 - 5 周 |
|
|
|
|
|
|
| 阶段 2:WebRTC / TURN / ZLM 媒体链路 | 完成 P2P、TURN、ZLMediaKit 基础切换 | 4 - 8 周 |
|
|
|
|
|
|
| 阶段 3:APP 与设备端联调 | APP、WiFi 锁、后台完整跑通呼叫、接听、挂断、切路 | 4 - 6 周 |
|
|
|
|
|
|
| 阶段 4:事件、日志、可观测、弱网优化 | 完成事件消费、质量上报、链路追踪、告警 | 2 - 4 周 |
|
|
|
|
|
|
| 阶段 5:AI 旁路接入 | 接入 `ai-gateway`、`xiaozhi_server` | 2 - 4 周 |
|
|
|
|
|
|
| 阶段 6:灰度上线与稳定性优化 | 压测、弱网测试、灰度、回滚方案 | 2 - 4 周 |
|
|
|
|
|
|
|
|
|
|
|
|
## 总周期预估
|
|
|
|
|
|
|
|
|
|
|
|
| 范围 | 周期 |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| 最小可用版本 MVP | 8 - 12 周 |
|
|
|
|
|
|
| 可灰度上线版本 | 12 - 16 周 |
|
|
|
|
|
|
| 含 AI、完整动态选路、完整可观测版本 | 16 - 24 周 |
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
# 二、模块开发周期、技术栈、难点与注意事项
|
|
|
|
|
|
|
|
|
|
|
|
## 1. `starlock` 租户应用层改造
|
|
|
|
|
|
|
|
|
|
|
|
### 模块定位
|
|
|
|
|
|
|
|
|
|
|
|
`starlock` 是 APP 的统一业务入口,负责:
|
|
|
|
|
|
|
|
|
|
|
|
- APP 登录鉴权
|
|
|
|
|
|
- 家庭 / 门锁归属判断
|
|
|
|
|
|
- 调用 `starcloud` 共享能力
|
|
|
|
|
|
- 调用 `session-orchestrator` 创建实时会话
|
|
|
|
|
|
- 下发短期会话权限
|
|
|
|
|
|
- 处理事件回调和业务通知
|
|
|
|
|
|
|
|
|
|
|
|
### 开发周期
|
|
|
|
|
|
|
|
|
|
|
|
**2 - 4 周**
|
|
|
|
|
|
|
|
|
|
|
|
如果现有 PHP 代码结构清晰,只做 API 编排,约 2 周。
|
|
|
|
|
|
如果需要整理权限、设备归属、租户模型,可能 4 周以上。
|
|
|
|
|
|
|
|
|
|
|
|
### 技术栈
|
|
|
|
|
|
|
|
|
|
|
|
| 类型 | 技术 |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| 后端语言 | PHP |
|
|
|
|
|
|
| 框架 | Laravel / ThinkPHP / Yii / 原有框架,按现状 |
|
|
|
|
|
|
| API | RESTful API |
|
|
|
|
|
|
| 认证 | JWT / Session / OAuth2 内部 token |
|
|
|
|
|
|
| 数据库 | MySQL / PostgreSQL |
|
|
|
|
|
|
| 缓存 | Redis |
|
|
|
|
|
|
| 内部调用 | HTTP / gRPC,可先 HTTP |
|
|
|
|
|
|
| 日志 | Monolog / ELK / Loki |
|
|
|
|
|
|
|
|
|
|
|
|
### 主要开发内容
|
|
|
|
|
|
|
|
|
|
|
|
- 新增“创建视频会话”接口
|
|
|
|
|
|
- 调用 `session-orchestrator` 创建 `sessionId`
|
|
|
|
|
|
- 根据用户、家庭、门锁关系做权限校验
|
|
|
|
|
|
- 返回 APP 所需短期 token、MQTT topic、媒体策略
|
|
|
|
|
|
- 处理 `MQTT event worker` 回调
|
|
|
|
|
|
- 处理 AI 会话状态回调
|
|
|
|
|
|
- 保留对 `starcloud` 的共享能力调用
|
|
|
|
|
|
|
|
|
|
|
|
### 难点
|
|
|
|
|
|
|
|
|
|
|
|
1. **权限边界**
|
|
|
|
|
|
- APP 用户是否有权访问某把锁
|
|
|
|
|
|
- 家庭成员、租户、渠道、套餐规则是否影响通话权限
|
|
|
|
|
|
|
|
|
|
|
|
2. **短期会话权限设计**
|
|
|
|
|
|
- APP 不能直接拿长期业务 token 去访问实时系统
|
|
|
|
|
|
- 需要生成短期、单会话、可过期的 token
|
|
|
|
|
|
|
|
|
|
|
|
3. **业务状态与实时状态解耦**
|
2026-04-27 14:46:21 +08:00
|
|
|
|
- `starlock` 不应该维护完整通话状态机
|
2026-04-27 14:42:20 +08:00
|
|
|
|
- 它只关心会话结果、事件回调和业务通知
|
|
|
|
|
|
|
|
|
|
|
|
4. **兼容旧链路**
|
|
|
|
|
|
- 旧 UDP 控制、旧 `scd/scrd/rpcd` 可能仍有设备在用
|
|
|
|
|
|
- 需要新旧能力并存一段时间
|
|
|
|
|
|
|
|
|
|
|
|
### 注意事项
|
|
|
|
|
|
|
|
|
|
|
|
- `starlock` 不要直接搬运 WebRTC signaling。
|
|
|
|
|
|
- APP 不应直接访问 `session-orchestrator` 的内部管理接口。
|
|
|
|
|
|
- 所有会话创建都必须经过设备归属和家庭权限校验。
|
|
|
|
|
|
- 短期 token 要绑定:
|
|
|
|
|
|
- `userId`
|
|
|
|
|
|
- `deviceId`
|
|
|
|
|
|
- `sessionId`
|
|
|
|
|
|
- 过期时间
|
|
|
|
|
|
- 权限范围
|
|
|
|
|
|
- 事件回调要做幂等处理,防止重复消费。
|
|
|
|
|
|
- 所有敏感操作要写审计日志。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 2. `starcloud` 共享业务能力对接
|
|
|
|
|
|
|
|
|
|
|
|
### 模块定位
|
|
|
|
|
|
|
|
|
|
|
|
`starcloud` 是共享业务平台,主要提供:
|
|
|
|
|
|
|
|
|
|
|
|
- 用户 / 权限策略
|
|
|
|
|
|
- 家庭 / 设备关系
|
|
|
|
|
|
- 套餐 / 计费
|
|
|
|
|
|
- 审计 / 风控
|
|
|
|
|
|
- 通用业务规则
|
|
|
|
|
|
|
|
|
|
|
|
### 开发周期
|
|
|
|
|
|
|
|
|
|
|
|
**1 - 3 周**
|
|
|
|
|
|
|
|
|
|
|
|
如果现有 API 完备,只需对接和字段适配,约 1 周。
|
|
|
|
|
|
如果需要补充共享能力 API,则需要 2 - 3 周。
|
|
|
|
|
|
|
|
|
|
|
|
### 技术栈
|
|
|
|
|
|
|
|
|
|
|
|
| 类型 | 技术 |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| 后端 | 现有 `starcloud` 技术栈 |
|
|
|
|
|
|
| API | REST / RPC |
|
|
|
|
|
|
| 鉴权 | 内部服务 token / AK-SK / OAuth2 |
|
|
|
|
|
|
| 数据库 | 现有数据库 |
|
|
|
|
|
|
| 缓存 | Redis |
|
|
|
|
|
|
| 审计 | 日志服务 / 审计表 |
|
|
|
|
|
|
|
|
|
|
|
|
### 主要开发内容
|
|
|
|
|
|
|
|
|
|
|
|
- 提供设备归属查询能力
|
|
|
|
|
|
- 提供用户权限策略查询能力
|
|
|
|
|
|
- 提供风控和审计接口
|
|
|
|
|
|
- 给 `starlock` 提供标准化业务 API
|
|
|
|
|
|
|
|
|
|
|
|
### 难点
|
|
|
|
|
|
|
|
|
|
|
|
- 多租户和跨项目能力边界容易混乱
|
|
|
|
|
|
- 共享模型与 `starlock` 定制逻辑可能重复
|
|
|
|
|
|
- 权限策略需要兼容现有用户体系
|
|
|
|
|
|
|
|
|
|
|
|
### 注意事项
|
|
|
|
|
|
|
|
|
|
|
|
- `starcloud` 不直接参与实时会话状态机。
|
|
|
|
|
|
- `starcloud` 只输出通用业务判断,不关心 WebRTC、BifroMQ、ZLM 细节。
|
|
|
|
|
|
- 通用能力和租户定制能力要分清。
|
|
|
|
|
|
- 不要把实时系统的 topic、signaling、media route 等细节侵入 `starcloud`。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 3. `session-orchestrator` 会话编排服务
|
|
|
|
|
|
|
|
|
|
|
|
### 模块定位
|
|
|
|
|
|
|
|
|
|
|
|
这是新实时系统的核心模块,负责:
|
|
|
|
|
|
|
|
|
|
|
|
- 创建会话
|
|
|
|
|
|
- 管理会话状态机
|
|
|
|
|
|
- 下发控制指令
|
|
|
|
|
|
- 处理 ACK / 超时 / 重试
|
|
|
|
|
|
- 编排 signaling topic
|
|
|
|
|
|
- 控制媒体选路
|
|
|
|
|
|
- 记录会话状态和质量数据
|
|
|
|
|
|
|
|
|
|
|
|
### 开发周期
|
|
|
|
|
|
|
|
|
|
|
|
**4 - 8 周**
|
|
|
|
|
|
|
|
|
|
|
|
MVP 版本 4 周左右。
|
|
|
|
|
|
完整支持状态机、切路、追踪、重试、幂等,建议预留 6 - 8 周。
|
|
|
|
|
|
|
|
|
|
|
|
### 技术栈
|
|
|
|
|
|
|
|
|
|
|
|
推荐技术栈:
|
|
|
|
|
|
|
|
|
|
|
|
| 类型 | 推荐 |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| 后端语言 | Go / Java / Node.js |
|
|
|
|
|
|
| 推荐优先级 | Go 或 Java 更适合长连接、并发和状态机 |
|
|
|
|
|
|
| Web 框架 | Go Fiber / Gin,Java Spring Boot |
|
|
|
|
|
|
| 内部 API | REST / gRPC |
|
|
|
|
|
|
| MQTT Client | Eclipse Paho / gmqtt / HiveMQ Client |
|
|
|
|
|
|
| 状态缓存 | Redis |
|
|
|
|
|
|
| 持久化 | MySQL / PostgreSQL |
|
2026-04-27 14:46:21 +08:00
|
|
|
|
| 消息序列 | Redis Stream / Kafka,可顺续引入 |
|
2026-04-27 14:42:20 +08:00
|
|
|
|
| 日志追踪 | OpenTelemetry |
|
|
|
|
|
|
| 指标 | Prometheus |
|
|
|
|
|
|
| 配置 | YAML / ENV / Nacos / Consul |
|
|
|
|
|
|
|
|
|
|
|
|
### 主要开发内容
|
|
|
|
|
|
|
|
|
|
|
|
- `CreateSession`
|
|
|
|
|
|
- `InviteDevice`
|
|
|
|
|
|
- `AcceptSession`
|
|
|
|
|
|
- `RejectSession`
|
|
|
|
|
|
- `StartSignaling`
|
|
|
|
|
|
- `ReportQuality`
|
|
|
|
|
|
- `SwitchRoute`
|
|
|
|
|
|
- `Hangup`
|
|
|
|
|
|
- `Timeout`
|
|
|
|
|
|
- `Terminate`
|
|
|
|
|
|
- 会话状态机
|
|
|
|
|
|
- MQTT topic 分配
|
|
|
|
|
|
- 短期 token 校验
|
|
|
|
|
|
- ACK / seq / retry
|
|
|
|
|
|
- 会话日志落库
|
|
|
|
|
|
- 媒体策略下发
|
|
|
|
|
|
|
|
|
|
|
|
### 推荐状态机
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
pending
|
|
|
|
|
|
-> ringing
|
|
|
|
|
|
-> accepted
|
|
|
|
|
|
-> connecting
|
|
|
|
|
|
-> connected
|
|
|
|
|
|
-> degraded
|
|
|
|
|
|
-> switching_route
|
|
|
|
|
|
-> recovered
|
|
|
|
|
|
-> ended
|
|
|
|
|
|
|
|
|
|
|
|
异常结束:
|
|
|
|
|
|
-> rejected
|
|
|
|
|
|
-> timeout
|
|
|
|
|
|
-> failed
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 难点
|
|
|
|
|
|
|
|
|
|
|
|
1. **状态一致性**
|
|
|
|
|
|
- APP、设备、云端三方状态容易不一致。
|
|
|
|
|
|
- 必须通过状态机和事件序列统一收敛。
|
|
|
|
|
|
|
|
|
|
|
|
2. **ACK 与超时控制**
|
|
|
|
|
|
- `invite` 发出后,设备可能离线、延迟、重复 ACK。
|
|
|
|
|
|
- 所有控制指令要有 `seq`、`ack`、`timeout`。
|
|
|
|
|
|
|
|
|
|
|
|
3. **动态选路**
|
|
|
|
|
|
- 什么时候从 P2P 切 TURN?
|
|
|
|
|
|
- 什么时候从 TURN 切 ZLM?
|
|
|
|
|
|
- 切路过程中如何不中断或少中断?
|
|
|
|
|
|
|
|
|
|
|
|
4. **幂等性**
|
|
|
|
|
|
- APP 重试创建会话
|
|
|
|
|
|
- 设备重复上报 accept
|
|
|
|
|
|
- MQTT 重复投递
|
|
|
|
|
|
- 都必须能安全处理
|
|
|
|
|
|
|
|
|
|
|
|
5. **分布式扩容**
|
|
|
|
|
|
- 多个 `session-orchestrator` 实例时,会话归属、锁、状态更新要处理好。
|
|
|
|
|
|
|
|
|
|
|
|
### 注意事项
|
|
|
|
|
|
|
|
|
|
|
|
- 会话 ID 必须全局唯一。
|
|
|
|
|
|
- 所有指令都要带:
|
|
|
|
|
|
- `sessionId`
|
|
|
|
|
|
- `eventId`
|
|
|
|
|
|
- `seq`
|
|
|
|
|
|
- `timestamp`
|
|
|
|
|
|
- `expireAt`
|
|
|
|
|
|
- `from`
|
|
|
|
|
|
- `to`
|
|
|
|
|
|
- 状态变更必须有合法状态迁移校验。
|
|
|
|
|
|
- 会话状态建议短期放 Redis,终态落 MySQL。
|
|
|
|
|
|
- 不建议在 MQTT retained message 中保存敏感 signaling。
|
|
|
|
|
|
- `session-orchestrator` 不搬运大媒体流。
|
|
|
|
|
|
- `session-orchestrator` 应只管控制面,不直接承载视频数据。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 4. `device-bootstrap` 设备接入服务
|
|
|
|
|
|
|
|
|
|
|
|
### 模块定位
|
|
|
|
|
|
|
|
|
|
|
|
设备首次或周期性接入时,通过该服务获取:
|
|
|
|
|
|
|
|
|
|
|
|
- 设备认证
|
|
|
|
|
|
- MQTT 连接参数
|
|
|
|
|
|
- 短期 MQTT 凭证
|
|
|
|
|
|
- 设备 topic 权限
|
|
|
|
|
|
- 设备能力配置
|
|
|
|
|
|
- 固件能力声明
|
|
|
|
|
|
|
|
|
|
|
|
### 开发周期
|
|
|
|
|
|
|
|
|
|
|
|
**2 - 4 周**
|
|
|
|
|
|
|
|
|
|
|
|
如果设备认证机制已存在,2 周左右。
|
|
|
|
|
|
如果需要重新设计设备证书、密钥、签名,3 - 4 周。
|
|
|
|
|
|
|
|
|
|
|
|
### 技术栈
|
|
|
|
|
|
|
|
|
|
|
|
| 类型 | 技术 |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| 后端语言 | Go / Java / PHP 均可 |
|
|
|
|
|
|
| API | HTTPS |
|
|
|
|
|
|
| 鉴权 | 设备证书 / 设备密钥 / HMAC 签名 |
|
|
|
|
|
|
| 存储 | MySQL |
|
|
|
|
|
|
| 缓存 | Redis |
|
|
|
|
|
|
| MQTT 权限 | BifroMQ Auth Provider / 自定义鉴权 |
|
|
|
|
|
|
|
|
|
|
|
|
### 主要开发内容
|
|
|
|
|
|
|
|
|
|
|
|
- 设备身份校验
|
|
|
|
|
|
- 颁发 MQTT username/password/token
|
|
|
|
|
|
- 生成设备 topic ACL
|
|
|
|
|
|
- 返回 BifroMQ 连接地址
|
|
|
|
|
|
- 返回心跳周期
|
|
|
|
|
|
- 返回设备配置
|
|
|
|
|
|
- 支持设备能力声明:
|
|
|
|
|
|
- 是否支持 WebRTC
|
|
|
|
|
|
- 是否支持 ZLM
|
|
|
|
|
|
- 是否支持 AI 音频旁路
|
|
|
|
|
|
- 是否支持 BLE 透传
|
|
|
|
|
|
|
|
|
|
|
|
### 难点
|
|
|
|
|
|
|
|
|
|
|
|
- 设备端时间不准导致签名过期判断失败
|
|
|
|
|
|
- 设备密钥泄露风险
|
|
|
|
|
|
- MQTT ACL 粒度设计
|
|
|
|
|
|
- 新旧设备兼容
|
|
|
|
|
|
|
|
|
|
|
|
### 注意事项
|
|
|
|
|
|
|
|
|
|
|
|
- 不要给设备长期固定 MQTT 密码。
|
|
|
|
|
|
- MQTT 凭证建议短期有效,可刷新。
|
|
|
|
|
|
- topic 权限必须最小化。
|
|
|
|
|
|
- 设备只能发布和订阅自己的 topic。
|
|
|
|
|
|
- 设备 capability 要版本化,方便后续灰度。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 5. Apache BifroMQ 模块
|
|
|
|
|
|
|
|
|
|
|
|
### 模块定位
|
|
|
|
|
|
|
|
|
|
|
|
BifroMQ 承担:
|
|
|
|
|
|
|
|
|
|
|
|
- 设备在线状态
|
|
|
|
|
|
- 发现
|
|
|
|
|
|
- MQTT signaling
|
|
|
|
|
|
- 事件总线
|
|
|
|
|
|
- APP 与设备信令通道
|
|
|
|
|
|
|
|
|
|
|
|
### 开发周期
|
|
|
|
|
|
|
|
|
|
|
|
**2 - 4 周**
|
|
|
|
|
|
|
|
|
|
|
|
部署和基础联调 1 - 2 周。
|
|
|
|
|
|
完整 ACL、认证、监控、压测,建议 3 - 4 周。
|
|
|
|
|
|
|
|
|
|
|
|
### 技术栈
|
|
|
|
|
|
|
|
|
|
|
|
| 类型 | 技术 |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| MQTT Broker | Apache BifroMQ |
|
|
|
|
|
|
| 协议 | MQTT 3.1.1 / MQTT 5 |
|
|
|
|
|
|
| APP 连接 | MQTT over WSS |
|
|
|
|
|
|
| 设备连接 | MQTT over TLS |
|
|
|
|
|
|
| 鉴权 | 自定义 Auth Provider |
|
|
|
|
|
|
| 监控 | Prometheus / Grafana |
|
|
|
|
|
|
| 日志 | Loki / ELK |
|
|
|
|
|
|
|
|
|
|
|
|
### Topic 设计建议
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
tenant/{tenantId}/device/{deviceId}/status
|
|
|
|
|
|
tenant/{tenantId}/device/{deviceId}/event
|
|
|
|
|
|
tenant/{tenantId}/session/{sessionId}/signal/app
|
|
|
|
|
|
tenant/{tenantId}/session/{sessionId}/signal/device
|
|
|
|
|
|
tenant/{tenantId}/session/{sessionId}/control
|
|
|
|
|
|
tenant/{tenantId}/session/{sessionId}/quality
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 难点
|
|
|
|
|
|
|
|
|
|
|
|
1. **topic 权限控制**
|
|
|
|
|
|
- APP 只能访问自己本次会话相关 topic。
|
|
|
|
|
|
- 设备只能访问自己所属 topic。
|
|
|
|
|
|
|
|
|
|
|
|
2. **在线状态判断**
|
|
|
|
|
|
- MQTT connected 不等于设备业务可用。
|
|
|
|
|
|
- 需要结合心跳、lastWill、设备能力状态。
|
|
|
|
|
|
|
|
|
|
|
|
3. **QoS 选择**
|
|
|
|
|
|
- signaling 可用 QoS 1。
|
|
|
|
|
|
- 质量上报可用 QoS 0。
|
|
|
|
|
|
- 控制指令建议 QoS 1 + 应用层 ACK。
|
|
|
|
|
|
|
|
|
|
|
|
4. **消息顺序**
|
|
|
|
|
|
- MQTT 不能替代完整状态机。
|
|
|
|
|
|
- 状态一致性仍应由 `session-orchestrator` 控制。
|
|
|
|
|
|
|
|
|
|
|
|
### 注意事项
|
|
|
|
|
|
|
|
|
|
|
|
- 不要通过 MQTT 传大视频流。
|
|
|
|
|
|
- 不要把长期敏感 token 放在 topic 或 payload 里。
|
|
|
|
|
|
- topic 命名要预留租户维度。
|
|
|
|
|
|
- MQTT payload 要版本化。
|
|
|
|
|
|
- retained message 谨慎使用,尤其是 signaling 类消息。
|
|
|
|
|
|
- LWT 遗嘱消息要设计好,用于设备离线通知。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 6. APP 端 `app-starlock` 改造
|
|
|
|
|
|
|
|
|
|
|
|
### 模块定位
|
|
|
|
|
|
|
|
|
|
|
|
APP 需要支持:
|
|
|
|
|
|
|
|
|
|
|
|
- 调用 `starlock` 创建会话
|
|
|
|
|
|
- 连接 BifroMQ
|
|
|
|
|
|
- 订阅 session topic
|
|
|
|
|
|
- WebRTC offer/answer/candidate
|
|
|
|
|
|
- 媒体链路质量上报
|
|
|
|
|
|
- 动态切路响应
|
|
|
|
|
|
- 弱网提示
|
|
|
|
|
|
- AI 辅助入口
|
|
|
|
|
|
|
|
|
|
|
|
### 开发周期
|
|
|
|
|
|
|
|
|
|
|
|
**4 - 8 周**
|
|
|
|
|
|
|
|
|
|
|
|
如果现有 Flutter 已有实时对讲能力,约 4 - 5 周。
|
|
|
|
|
|
如果 WebRTC 从零接入,建议 6 - 8 周。
|
|
|
|
|
|
|
|
|
|
|
|
### 技术栈
|
|
|
|
|
|
|
|
|
|
|
|
| 类型 | 技术 |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| APP 框架 | Flutter |
|
|
|
|
|
|
| WebRTC | flutter_webrtc |
|
|
|
|
|
|
| MQTT | mqtt_client / 其他 Flutter MQTT SDK |
|
|
|
|
|
|
| 网络 | Dio |
|
|
|
|
|
|
| 状态管理 | Riverpod / Bloc / Provider |
|
|
|
|
|
|
| 本地存储 | shared_preferences / hive |
|
|
|
|
|
|
| 日志 | Sentry / 自建日志上报 |
|
|
|
|
|
|
| 推送 | FCM / APNs / 厂商推送 |
|
|
|
|
|
|
|
|
|
|
|
|
### 主要开发内容
|
|
|
|
|
|
|
|
|
|
|
|
- 会话创建 API
|
|
|
|
|
|
- MQTT over WSS 连接
|
|
|
|
|
|
- WebRTC PeerConnection
|
|
|
|
|
|
- ICE candidate 处理
|
|
|
|
|
|
- offer/answer 交换
|
|
|
|
|
|
- TURN 配置
|
|
|
|
|
|
- ZLM 播放 / 推流能力接入
|
|
|
|
|
|
- route switch 指令处理
|
|
|
|
|
|
- 通话 UI 状态机
|
|
|
|
|
|
- 通话质量上报
|
|
|
|
|
|
- 异常提示和重连
|
|
|
|
|
|
|
|
|
|
|
|
### 难点
|
|
|
|
|
|
|
|
|
|
|
|
1. **Flutter WebRTC 稳定性**
|
|
|
|
|
|
- Android 和 iOS 行为不同。
|
|
|
|
|
|
- 后台、锁屏、权限、音频路由复杂。
|
|
|
|
|
|
|
|
|
|
|
|
2. **弱网处理**
|
|
|
|
|
|
- 网络切换 WiFi/4G
|
|
|
|
|
|
- ICE reconnect
|
|
|
|
|
|
- MQTT 断线重连
|
|
|
|
|
|
- 媒体重连
|
|
|
|
|
|
|
|
|
|
|
|
3. **状态同步**
|
|
|
|
|
|
- APP UI 状态必须跟云端会话状态保持一致。
|
|
|
|
|
|
- 不能只靠本地 WebRTC 状态判断。
|
|
|
|
|
|
|
|
|
|
|
|
4. **音频权限和回声消除**
|
|
|
|
|
|
- 双向语音容易出现回声、啸叫、音量问题。
|
|
|
|
|
|
|
|
|
|
|
|
### 注意事项
|
|
|
|
|
|
|
|
|
|
|
|
- APP 不要保存长期 MQTT 密钥。
|
|
|
|
|
|
- APP 进入后台时要处理 MQTT 和 WebRTC 生命周期。
|
|
|
|
|
|
- 会话失败要区分:
|
|
|
|
|
|
- 设备离线
|
|
|
|
|
|
- 权限不足
|
|
|
|
|
|
- signaling 超时
|
|
|
|
|
|
- ICE 失败
|
|
|
|
|
|
- ZLM 失败
|
|
|
|
|
|
- 所有通话状态变化都要上报。
|
|
|
|
|
|
- iOS 需要特别注意后台音视频权限和推送唤醒策略。
|
|
|
|
|
|
- Android 需要注意不同厂商后台保活限制。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 7. WiFi 网关锁 / 设备端改造
|
|
|
|
|
|
|
|
|
|
|
|
### 模块定位
|
|
|
|
|
|
|
|
|
|
|
|
WiFi 锁作为网关设备,需要支持:
|
|
|
|
|
|
|
|
|
|
|
|
- HTTPS bootstrap
|
|
|
|
|
|
- MQTT/TLS 连接
|
|
|
|
|
|
- 在线状态上报
|
|
|
|
|
|
- 会话 invite/accept/reject/hangup
|
|
|
|
|
|
- WebRTC 采集、编码、推流
|
|
|
|
|
|
- TURN / ZLM / relay 切换
|
|
|
|
|
|
- AI 音频旁路
|
|
|
|
|
|
- BLE 锁透传
|
|
|
|
|
|
|
|
|
|
|
|
### 开发周期
|
|
|
|
|
|
|
|
|
|
|
|
**6 - 12 周**
|
|
|
|
|
|
|
|
|
|
|
|
如果设备端已有音视频 SDK 和 WebRTC 能力,6 - 8 周。
|
|
|
|
|
|
如果从零接入 WebRTC,尤其是嵌入式平台,可能 12 周以上。
|
|
|
|
|
|
|
|
|
|
|
|
### 技术栈
|
|
|
|
|
|
|
|
|
|
|
|
| 类型 | 技术 |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| 语言 | C / C++ |
|
|
|
|
|
|
| MQTT | Eclipse Paho Embedded / mosquitto client / 自研 |
|
|
|
|
|
|
| TLS | mbedTLS / OpenSSL |
|
|
|
|
|
|
| WebRTC | libwebrtc / Pion 设备适配 / vendor SDK |
|
|
|
|
|
|
| 编码 | H.264 / H.265 / AAC / Opus |
|
|
|
|
|
|
| 媒体 | GStreamer / FFmpeg / 设备厂商 SDK |
|
|
|
|
|
|
| 存储 | Flash / 本地配置 |
|
|
|
|
|
|
| 日志 | 本地环形日志 + 云端上报 |
|
|
|
|
|
|
|
|
|
|
|
|
### 主要开发内容
|
|
|
|
|
|
|
|
|
|
|
|
- bootstrap 接入
|
|
|
|
|
|
- MQTT topic 订阅和发布
|
|
|
|
|
|
- 设备能力声明
|
|
|
|
|
|
- 接收 `invite`
|
|
|
|
|
|
- 发送 `ringing/accept/reject`
|
|
|
|
|
|
- signaling 处理
|
|
|
|
|
|
- WebRTC 建链
|
|
|
|
|
|
- TURN 支持
|
|
|
|
|
|
- ZLM 推流或 WebRTC 接入
|
|
|
|
|
|
- 质量指标采集
|
|
|
|
|
|
- route switch 响应
|
|
|
|
|
|
- 会话结束清理
|
2026-04-27 14:46:21 +08:00
|
|
|
|
- AI旁路转发
|
2026-04-27 14:42:20 +08:00
|
|
|
|
|
|
|
|
|
|
### 难点
|
|
|
|
|
|
|
|
|
|
|
|
1. **设备性能限制**
|
|
|
|
|
|
- CPU、内存、编码能力有限。
|
|
|
|
|
|
- WebRTC 对资源要求高。
|
|
|
|
|
|
|
|
|
|
|
|
2. **嵌入式 WebRTC 集成难**
|
|
|
|
|
|
- ICE、DTLS、SRTP、NAT 穿透复杂。
|
|
|
|
|
|
- SDK 移植成本高。
|
|
|
|
|
|
|
|
|
|
|
|
3. **音视频编码兼容**
|
|
|
|
|
|
- APP、ZLM、WebRTC 对 codec 支持要统一。
|
|
|
|
|
|
- H.264 profile、packetization mode 要注意。
|
|
|
|
|
|
|
|
|
|
|
|
4. **切路过程中资源释放**
|
|
|
|
|
|
- P2P 切 ZLM 时要释放旧连接。
|
|
|
|
|
|
- 防止摄像头、麦克风、编码器被占用。
|
|
|
|
|
|
|
|
|
|
|
|
5. **断网恢复**
|
|
|
|
|
|
- 设备重连后要恢复 MQTT 状态。
|
|
|
|
|
|
- 旧会话要能被云端清理。
|
|
|
|
|
|
|
|
|
|
|
|
### 注意事项
|
|
|
|
|
|
|
|
|
|
|
|
- 设备端必须实现控制指令 ACK。
|
|
|
|
|
|
- 设备端所有消息要带 `sessionId` 和 `seq`。
|
|
|
|
|
|
- 设备端不能信任任意 MQTT 消息,必须校验 token 或签名。
|
|
|
|
|
|
- 摄像头、麦克风只能被一个会话独占,除非明确支持多路。
|
|
|
|
|
|
- 本地日志非常重要,否则现场问题很难定位。
|
|
|
|
|
|
- 如果设备端 WebRTC 难度过高,可以第一阶段优先走 ZLMediaKit 或厂商 SDK,再逐步补 P2P。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 8. WebRTC / TURN 媒体链路模块
|
|
|
|
|
|
|
|
|
|
|
|
### 模块定位
|
|
|
|
|
|
|
|
|
|
|
|
负责 APP 与设备之间的实时音视频链路:
|
|
|
|
|
|
|
|
|
|
|
|
- 优先 P2P
|
|
|
|
|
|
- P2P 不通走 TURN
|
|
|
|
|
|
- 弱网时可切 ZLM
|
|
|
|
|
|
- 最终兜底走中心转发
|
|
|
|
|
|
|
|
|
|
|
|
### 开发周期
|
|
|
|
|
|
|
|
|
|
|
|
**4 - 8 周**
|
|
|
|
|
|
|
|
|
|
|
|
APP、设备、服务端三方联调复杂,建议至少预留 1 个月。
|
|
|
|
|
|
|
|
|
|
|
|
### 技术栈
|
|
|
|
|
|
|
|
|
|
|
|
| 类型 | 技术 |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| WebRTC | libwebrtc / flutter_webrtc |
|
|
|
|
|
|
| STUN/TURN | coturn |
|
|
|
|
|
|
| 加密 | DTLS-SRTP |
|
|
|
|
|
|
| NAT 穿透 | ICE |
|
|
|
|
|
|
| 编码 | H.264 / Opus |
|
|
|
|
|
|
| 质量监控 | getStats / 自定义质量上报 |
|
|
|
|
|
|
|
|
|
|
|
|
### 主要开发内容
|
|
|
|
|
|
|
|
|
|
|
|
- ICE server 配置
|
|
|
|
|
|
- offer/answer
|
|
|
|
|
|
- candidate 收集和交换
|
|
|
|
|
|
- TURN credential
|
|
|
|
|
|
- 质量上报
|
|
|
|
|
|
- P2P / TURN 判定
|
|
|
|
|
|
- ICE restart
|
|
|
|
|
|
- 通话异常恢复
|
|
|
|
|
|
|
|
|
|
|
|
### 难点
|
|
|
|
|
|
|
|
|
|
|
|
- NAT 类型复杂
|
|
|
|
|
|
- 对称 NAT 下 P2P 失败率高
|
|
|
|
|
|
- TURN 成本高,带宽压力大
|
|
|
|
|
|
- ICE 状态和业务状态不完全一致
|
|
|
|
|
|
- 移动网络切换容易断流
|
|
|
|
|
|
|
|
|
|
|
|
### 注意事项
|
|
|
|
|
|
|
|
|
|
|
|
- TURN 账号必须短期有效。
|
|
|
|
|
|
- TURN 带宽成本要评估。
|
|
|
|
|
|
- 不要把 TURN 当成无限免费兜底。
|
|
|
|
|
|
- WebRTC 质量指标要持续上报:
|
|
|
|
|
|
- RTT
|
|
|
|
|
|
- packet loss
|
|
|
|
|
|
- jitter
|
|
|
|
|
|
- bitrate
|
|
|
|
|
|
- candidate type
|
|
|
|
|
|
- frame drop
|
|
|
|
|
|
- 首版可以先实现“失败后重建到 ZLM”,不要一开始追求无感切换。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 9. `ZLMediaKit` 中心转发模块
|
|
|
|
|
|
|
|
|
|
|
|
### 模块定位
|
|
|
|
|
|
|
|
|
|
|
|
ZLMediaKit 用于:
|
|
|
|
|
|
|
|
|
|
|
|
- 弱网优先转发
|
|
|
|
|
|
- P2P/TURN 失败后的媒体兜底
|
|
|
|
|
|
- 标准化流媒体接入
|
|
|
|
|
|
- 后续录像、截图、事件视频处理
|
|
|
|
|
|
|
|
|
|
|
|
### 开发周期
|
|
|
|
|
|
|
|
|
|
|
|
**3 - 6 周**
|
|
|
|
|
|
|
|
|
|
|
|
基础部署和推拉流 1 - 2 周。
|
|
|
|
|
|
与 APP、设备、鉴权、会话状态打通,约 3 - 6 周。
|
|
|
|
|
|
|
|
|
|
|
|
### 技术栈
|
|
|
|
|
|
|
|
|
|
|
|
| 类型 | 技术 |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| 流媒体服务 | ZLMediaKit |
|
|
|
|
|
|
| 协议 | WebRTC / RTSP / RTMP / HLS / HTTP-FLV |
|
|
|
|
|
|
| 编码 | H.264 / AAC / Opus |
|
|
|
|
|
|
| 鉴权 | ZLM hook + 业务鉴权 |
|
|
|
|
|
|
| 部署 | Docker / systemd |
|
|
|
|
|
|
| 负载均衡 | Nginx / SLB |
|
|
|
|
|
|
| 监控 | Prometheus exporter / 日志采集 |
|
|
|
|
|
|
|
|
|
|
|
|
### 主要开发内容
|
|
|
|
|
|
|
|
|
|
|
|
- ZLM 部署
|
|
|
|
|
|
- 推流地址生成
|
|
|
|
|
|
- 播放地址生成
|
|
|
|
|
|
- Hook 鉴权
|
|
|
|
|
|
- 流开始 / 结束事件回调
|
|
|
|
|
|
- 与 `session-orchestrator` 对接
|
|
|
|
|
|
- APP 播放适配
|
|
|
|
|
|
- 设备推流适配
|
|
|
|
|
|
- 异常断流重试
|
|
|
|
|
|
|
|
|
|
|
|
### 难点
|
|
|
|
|
|
|
|
|
|
|
|
1. **协议选择**
|
|
|
|
|
|
- 设备推什么协议?
|
|
|
|
|
|
- APP 拉什么协议?
|
|
|
|
|
|
- 是否都走 WebRTC?
|
|
|
|
|
|
|
|
|
|
|
|
2. **延迟控制**
|
|
|
|
|
|
- HLS 延迟高,不适合实时对讲。
|
|
|
|
|
|
- WebRTC / RTMP / HTTP-FLV 要按实际需求选。
|
|
|
|
|
|
|
|
|
|
|
|
3. **双向语音**
|
|
|
|
|
|
- 只看视频容易,双向对讲更复杂。
|
|
|
|
|
|
- 要确认 ZLM 在当前方案中如何承载上行音频。
|
|
|
|
|
|
|
|
|
|
|
|
4. **鉴权和防盗链**
|
|
|
|
|
|
- 推流 / 播放 URL 必须短期有效。
|
|
|
|
|
|
- 不能裸露固定流地址。
|
|
|
|
|
|
|
|
|
|
|
|
### 注意事项
|
|
|
|
|
|
|
|
|
|
|
|
- 弱网优先 ZLM 是合理的,但要明确“实时对讲”的延迟指标。
|
|
|
|
|
|
- 首版建议只做一套主协议,避免 RTMP、RTSP、WebRTC、FLV 全部都上。
|
|
|
|
|
|
- ZLM 的 hook 回调要和 `session-orchestrator` 状态机打通。
|
|
|
|
|
|
- 流 ID 要绑定 `sessionId`。
|
|
|
|
|
|
- 推流和播放权限必须过期。
|
|
|
|
|
|
- 要有自动清理僵尸流机制。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 10. `media-relay` 中心转发兜底模块
|
|
|
|
|
|
|
|
|
|
|
|
### 模块定位
|
|
|
|
|
|
|
|
|
|
|
|
`media-relay` 是最终兜底。
|
|
|
|
|
|
但你文档里已经明确:**优先采用 ZLMediaKit 落地,通常不需要长期维护自研 relay。**
|
|
|
|
|
|
|
|
|
|
|
|
### 开发周期
|
|
|
|
|
|
|
|
|
|
|
|
| 方案 | 周期 |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| 不自研,直接用 ZLMediaKit 承担 | 0 - 1 周设计适配 |
|
|
|
|
|
|
| 轻量封装 ZLM relay API | 2 - 3 周 |
|
|
|
|
|
|
| 自研完整音视频 relay | 8 - 16 周,不建议第一阶段做 |
|
|
|
|
|
|
|
|
|
|
|
|
### 技术栈
|
|
|
|
|
|
|
|
|
|
|
|
如果不自研:
|
|
|
|
|
|
|
|
|
|
|
|
| 类型 | 技术 |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| Relay 实现 | ZLMediaKit |
|
|
|
|
|
|
| 控制层 | `session-orchestrator` |
|
|
|
|
|
|
| 鉴权 | ZLM hook |
|
|
|
|
|
|
| 监控 | Prometheus / 日志 |
|
|
|
|
|
|
|
|
|
|
|
|
如果自研:
|
|
|
|
|
|
|
|
|
|
|
|
| 类型 | 技术 |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| 语言 | C++ / Go |
|
|
|
|
|
|
| 媒体协议 | RTP / SRTP / WebRTC |
|
|
|
|
|
|
| 编码处理 | FFmpeg / GStreamer |
|
|
|
|
|
|
| NAT | ICE / TURN |
|
|
|
|
|
|
| 难度 | 高 |
|
|
|
|
|
|
|
|
|
|
|
|
### 难点
|
|
|
|
|
|
|
|
|
|
|
|
- 自研媒体转发成本极高
|
|
|
|
|
|
- 音视频同步、抖动缓冲、拥塞控制都复杂
|
|
|
|
|
|
- 稳定性和性能验证成本高
|
|
|
|
|
|
|
|
|
|
|
|
### 注意事项
|
|
|
|
|
|
|
|
|
|
|
|
- 第一阶段不建议自研 `media-relay`。
|
|
|
|
|
|
- 先让 `media-relay` 成为逻辑模块,由 ZLMediaKit 实现。
|
|
|
|
|
|
- 后续只有在 ZLM 无法满足业务需求时再考虑自研。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 11. `MQTT event worker` / 原 `event_listener` 演进
|
|
|
|
|
|
|
|
|
|
|
|
### 模块定位
|
|
|
|
|
|
|
|
|
|
|
|
负责消费设备事件和实时事件:
|
|
|
|
|
|
|
|
|
|
|
|
- 门锁事件
|
|
|
|
|
|
- 设备上下线
|
|
|
|
|
|
- 通话事件
|
|
|
|
|
|
- 媒体事件
|
|
|
|
|
|
- AI 事件
|
|
|
|
|
|
- 图片 / 视频后处理
|
|
|
|
|
|
- 回调 `starlock`
|
|
|
|
|
|
|
|
|
|
|
|
### 开发周期
|
|
|
|
|
|
|
|
|
|
|
|
**2 - 4 周**
|
|
|
|
|
|
|
|
|
|
|
|
### 技术栈
|
|
|
|
|
|
|
|
|
|
|
|
| 类型 | 技术 |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| 后端语言 | Go / Java / PHP Worker / Node.js |
|
|
|
|
|
|
| 消息来源 | BifroMQ MQTT |
|
|
|
|
|
|
| 队列 | Redis Stream / Kafka / RabbitMQ,可选 |
|
|
|
|
|
|
| 存储 | MySQL / Redis |
|
|
|
|
|
|
| 回调 | HTTP |
|
|
|
|
|
|
| 重试 | 延迟队列 / 定时任务 |
|
|
|
|
|
|
|
|
|
|
|
|
### 主要开发内容
|
|
|
|
|
|
|
|
|
|
|
|
- MQTT 事件订阅
|
|
|
|
|
|
- 事件解析
|
|
|
|
|
|
- 事件幂等
|
|
|
|
|
|
- 回调 `starlock`
|
|
|
|
|
|
- 失败重试
|
|
|
|
|
|
- 死信队列
|
|
|
|
|
|
- 事件日志落库
|
|
|
|
|
|
- 媒体后处理触发
|
|
|
|
|
|
|
|
|
|
|
|
### 难点
|
|
|
|
|
|
|
|
|
|
|
|
- MQTT 事件可能重复
|
|
|
|
|
|
- 设备事件顺序可能乱
|
|
|
|
|
|
- 回调失败后要重试
|
|
|
|
|
|
- 事件消费不能阻塞主实时链路
|
|
|
|
|
|
|
|
|
|
|
|
### 注意事项
|
|
|
|
|
|
|
|
|
|
|
|
- 每个事件必须有唯一 `eventId`。
|
|
|
|
|
|
- 回调 `starlock` 要支持幂等。
|
|
|
|
|
|
- 不要在 worker 中做耗时媒体处理,应该异步化。
|
|
|
|
|
|
- 事件处理失败要可追踪、可重放。
|
|
|
|
|
|
- 事件 schema 要版本化。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 12. `realtime-store` 实时状态与日志缓存
|
|
|
|
|
|
|
|
|
|
|
|
### 模块定位
|
|
|
|
|
|
|
|
|
|
|
|
用于保存:
|
|
|
|
|
|
|
2026-04-27 14:46:21 +08:00
|
|
|
|
- 会话临时状态
|
2026-04-27 14:42:20 +08:00
|
|
|
|
- 会话质量指标
|
|
|
|
|
|
- signaling 摘要
|
|
|
|
|
|
- route 切换记录
|
|
|
|
|
|
- 调试日志
|
|
|
|
|
|
- 会话终态
|
|
|
|
|
|
|
|
|
|
|
|
### 开发周期
|
|
|
|
|
|
|
|
|
|
|
|
**1 - 3 周**
|
|
|
|
|
|
|
|
|
|
|
|
### 技术栈
|
|
|
|
|
|
|
|
|
|
|
|
| 类型 | 技术 |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| 热状态 | Redis |
|
|
|
|
|
|
| 持久化 | MySQL / PostgreSQL |
|
|
|
|
|
|
| 日志 | Loki / Elasticsearch |
|
|
|
|
|
|
| 指标 | Prometheus |
|
|
|
|
|
|
| 链路追踪 | OpenTelemetry |
|
|
|
|
|
|
|
|
|
|
|
|
### 数据建议
|
|
|
|
|
|
|
|
|
|
|
|
#### Redis
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
session:{sessionId}:state
|
|
|
|
|
|
session:{sessionId}:participants
|
|
|
|
|
|
session:{sessionId}:route
|
|
|
|
|
|
session:{sessionId}:quality
|
|
|
|
|
|
device:{deviceId}:online
|
|
|
|
|
|
device:{deviceId}:capability
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### MySQL
|
|
|
|
|
|
|
|
|
|
|
|
- `realtime_session`
|
|
|
|
|
|
- `realtime_session_event`
|
|
|
|
|
|
- `realtime_quality_report`
|
|
|
|
|
|
- `realtime_route_switch`
|
|
|
|
|
|
- `device_online_log`
|
|
|
|
|
|
|
|
|
|
|
|
### 难点
|
|
|
|
|
|
|
|
|
|
|
|
- 热状态和持久化状态一致性
|
|
|
|
|
|
- 会话结束后的资源清理
|
|
|
|
|
|
- 日志量较大
|
|
|
|
|
|
- 敏感数据脱敏
|
|
|
|
|
|
|
|
|
|
|
|
### 注意事项
|
|
|
|
|
|
|
|
|
|
|
|
- Redis key 必须设置 TTL。
|
|
|
|
|
|
- signaling 内容不建议完整长期保存,只保存必要摘要。
|
|
|
|
|
|
- 质量数据可以采样,不要无限写入。
|
|
|
|
|
|
- 终态必须落库,便于审计和问题排查。
|
|
|
|
|
|
- 需要按 `sessionId` 能快速查完整链路。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 13. `ai-gateway` 与 `xiaozhi_server` AI 旁路模块
|
|
|
|
|
|
|
|
|
|
|
|
### 模块定位
|
|
|
|
|
|
|
|
|
|
|
|
AI 不进入主通话状态机,而是旁路能力:
|
|
|
|
|
|
|
|
|
|
|
|
- 设备音频旁路到 AI
|
|
|
|
|
|
- APP AI 辅助模式
|
|
|
|
|
|
- AI 结果回传 `starlock`
|
|
|
|
|
|
- 不影响主对讲链路
|
|
|
|
|
|
|
|
|
|
|
|
### 开发周期
|
|
|
|
|
|
|
|
|
|
|
|
**2 - 4 周**
|
|
|
|
|
|
|
|
|
|
|
|
如果只是接入已有 `xiaozhi_server`,2 周左右。
|
|
|
|
|
|
如果需要实时音频流、唤醒词、语音识别、语音合成,4 周以上。
|
|
|
|
|
|
|
|
|
|
|
|
### 技术栈
|
|
|
|
|
|
|
|
|
|
|
|
| 类型 | 技术 |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| 网关语言 | Go / Python / Node.js |
|
|
|
|
|
|
| AI 服务 | xiaozhi_server |
|
|
|
|
|
|
| 音频协议 | WebSocket / RTP / HTTP streaming |
|
|
|
|
|
|
| 编码 | PCM / Opus / AAC |
|
|
|
|
|
|
| 鉴权 | 短期 token |
|
|
|
|
|
|
| 回调 | HTTP 到 `starlock` |
|
|
|
|
|
|
|
|
|
|
|
|
### 主要开发内容
|
|
|
|
|
|
|
|
|
|
|
|
- AI 会话创建
|
|
|
|
|
|
- 音频旁路接入
|
|
|
|
|
|
- AI 服务转发
|
|
|
|
|
|
- AI 结果回调
|
|
|
|
|
|
- 会话结束清理
|
|
|
|
|
|
- AI 异常不影响主通话
|
|
|
|
|
|
|
|
|
|
|
|
### 难点
|
|
|
|
|
|
|
|
|
|
|
|
- 音频格式转换
|
|
|
|
|
|
- 实时性要求
|
|
|
|
|
|
- AI 服务异常隔离
|
|
|
|
|
|
- 主通话和 AI 旁路资源竞争
|
|
|
|
|
|
- 隐私和权限控制
|
|
|
|
|
|
|
|
|
|
|
|
### 注意事项
|
|
|
|
|
|
|
|
|
|
|
|
- AI 不要阻塞主对讲链路。
|
|
|
|
|
|
- AI 失败不能导致视频通话失败。
|
|
|
|
|
|
- AI 音频采集要经过用户授权。
|
|
|
|
|
|
- AI 数据要做隐私合规处理。
|
|
|
|
|
|
- AI 事件要独立状态机,不能混入主通话状态机。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 14. 运维部署与基础设施模块
|
|
|
|
|
|
|
|
|
|
|
|
### 模块定位
|
|
|
|
|
|
|
|
|
|
|
|
负责部署:
|
|
|
|
|
|
|
|
|
|
|
|
- BifroMQ
|
|
|
|
|
|
- `session-orchestrator`
|
|
|
|
|
|
- `device-bootstrap`
|
|
|
|
|
|
- coturn
|
|
|
|
|
|
- ZLMediaKit
|
|
|
|
|
|
- MQTT event worker
|
|
|
|
|
|
- Redis
|
|
|
|
|
|
- MySQL
|
|
|
|
|
|
- 日志、监控、告警
|
|
|
|
|
|
|
|
|
|
|
|
### 开发周期
|
|
|
|
|
|
|
|
|
|
|
|
**3 - 6 周**
|
|
|
|
|
|
|
|
|
|
|
|
MVP Docker Compose 1 - 2 周。
|
|
|
|
|
|
生产高可用部署 4 - 6 周。
|
|
|
|
|
|
|
|
|
|
|
|
### 技术栈
|
|
|
|
|
|
|
|
|
|
|
|
| 类型 | 技术 |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| 容器 | Docker |
|
|
|
|
|
|
| 编排 | Docker Compose / Kubernetes |
|
|
|
|
|
|
| 网关 | Nginx / Ingress |
|
|
|
|
|
|
| 证书 | Let's Encrypt / 企业证书 |
|
|
|
|
|
|
| 监控 | Prometheus + Grafana |
|
|
|
|
|
|
| 日志 | Loki / ELK |
|
|
|
|
|
|
| 追踪 | Jaeger / Tempo |
|
|
|
|
|
|
| CI/CD | GitLab CI / GitHub Actions |
|
|
|
|
|
|
| 配置 | ENV / Secret / ConfigMap |
|
|
|
|
|
|
|
|
|
|
|
|
### 难点
|
|
|
|
|
|
|
|
|
|
|
|
- BifroMQ 集群部署
|
|
|
|
|
|
- TURN 公网 IP 和端口规划
|
|
|
|
|
|
- ZLM 带宽和并发压力
|
|
|
|
|
|
- 日志量控制
|
|
|
|
|
|
- 多服务之间配置复杂
|
|
|
|
|
|
- 灰度和回滚
|
|
|
|
|
|
|
|
|
|
|
|
### 注意事项
|
|
|
|
|
|
|
|
|
|
|
|
- coturn 必须部署在公网可达节点。
|
|
|
|
|
|
- TURN UDP 端口范围要提前开放。
|
|
|
|
|
|
- ZLM 和 TURN 带宽要按峰值计算。
|
|
|
|
|
|
- 所有服务要有健康检查。
|
|
|
|
|
|
- 生产环境密钥不能写在配置文件仓库中。
|
|
|
|
|
|
- 日志要设置保留周期,避免磁盘被打满。
|
|
|
|
|
|
- 要准备一键回滚方案。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
# 三、模块优先级建议
|
|
|
|
|
|
|
|
|
|
|
|
## P0:第一阶段必须完成
|
|
|
|
|
|
|
|
|
|
|
|
| 模块 | 说明 |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| `starlock` 会话入口 | APP 创建会话必须依赖 |
|
|
|
|
|
|
| `session-orchestrator` | 新实时系统核心 |
|
|
|
|
|
|
| `device-bootstrap` | 设备拿 MQTT 凭证 |
|
|
|
|
|
|
| BifroMQ | 发现、在线、信令 |
|
|
|
|
|
|
| APP MQTT + WebRTC 基础 | APP 端通话能力 |
|
|
|
|
|
|
| 设备 MQTT + WebRTC/ZLM 基础 | 设备端通话能力 |
|
|
|
|
|
|
| coturn | P2P 失败补位 |
|
|
|
|
|
|
| ZLMediaKit 基础转发 | 弱网和失败兜底 |
|
|
|
|
|
|
| `MQTT event worker` | 事件回调 |
|
|
|
|
|
|
| 基础监控日志 | 联调和上线必需 |
|
|
|
|
|
|
|
|
|
|
|
|
## P1:灰度上线前建议完成
|
|
|
|
|
|
|
|
|
|
|
|
| 模块 | 说明 |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| 完整 ACK / 超时 / 重试 | 提升状态一致性 |
|
|
|
|
|
|
| 质量指标上报 | 支撑动态选路 |
|
|
|
|
|
|
| 动态 route switch | P2P / TURN / ZLM 切换 |
|
|
|
|
|
|
| 会话追踪 | 定位问题 |
|
|
|
|
|
|
| ZLM hook 鉴权 | 防止盗流 |
|
|
|
|
|
|
| TURN 临时凭证 | 安全必需 |
|
|
|
|
|
|
| 异常恢复 | 网络切换、断线重连 |
|
|
|
|
|
|
| 压测和弱网测试 | 上线前必需 |
|
|
|
|
|
|
|
|
|
|
|
|
## P2:后续增强
|
|
|
|
|
|
|
|
|
|
|
|
| 模块 | 说明 |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| AI 旁路 | 不影响主链路,可后置 |
|
|
|
|
|
|
| 自研 media-relay | 如 ZLM 不满足再考虑 |
|
|
|
|
|
|
| 高级网络评分模型 | 根据数据逐步优化 |
|
|
|
|
|
|
| 多区域接入 | 用户量上来后再做 |
|
|
|
|
|
|
| 完整录像 / 云存储 | 按业务套餐推进 |
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
# 四、关键技术难点总结
|
|
|
|
|
|
|
|
|
|
|
|
## 1. 控制面和媒体面解耦
|
|
|
|
|
|
|
|
|
|
|
|
难点不是画架构,而是实现时防止耦合:
|
|
|
|
|
|
|
|
|
|
|
|
- `session-orchestrator` 不能直接处理视频流
|
|
|
|
|
|
- BifroMQ 不能传大媒体
|
|
|
|
|
|
- `starlock` 不能变成实时状态机
|
|
|
|
|
|
- ZLM 不能承载业务权限判断
|
|
|
|
|
|
|
|
|
|
|
|
正确边界是:
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
starlock:业务权限
|
|
|
|
|
|
session-orchestrator:会话状态机
|
|
|
|
|
|
BifroMQ:信令和事件通道
|
|
|
|
|
|
WebRTC/ZLM/TURN:媒体链路
|
|
|
|
|
|
event worker:异步事件处理
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 2. 会话状态一致性
|
|
|
|
|
|
|
|
|
|
|
|
这是整个方案最大的工程难点之一。
|
|
|
|
|
|
|
|
|
|
|
|
必须解决:
|
|
|
|
|
|
|
|
|
|
|
|
- APP 发起了但设备没收到
|
|
|
|
|
|
- 设备 accept 了但 APP 已取消
|
|
|
|
|
|
- MQTT 重连导致重复消息
|
|
|
|
|
|
- WebRTC 连上但云端状态还是 connecting
|
|
|
|
|
|
- P2P 断了但双方状态不一致
|
|
|
|
|
|
- 会话结束后资源没释放
|
|
|
|
|
|
|
|
|
|
|
|
建议所有状态变化都通过 `session-orchestrator` 收敛。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 3. 媒体动态选路
|
|
|
|
|
|
|
|
|
|
|
|
动态选路不要一开始做得太复杂。
|
|
|
|
|
|
|
|
|
|
|
|
建议第一版策略:
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
默认尝试 P2P
|
|
|
|
|
|
-> ICE 失败或超时,切 TURN
|
|
|
|
|
|
-> TURN 仍失败,切 ZLMediaKit
|
|
|
|
|
|
-> ZLMediaKit 失败,提示通话失败或走旧 relay
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
弱网优化版再做:
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
根据 RTT、丢包、jitter、candidate type、带宽评估是否提前切 ZLM
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 4. 设备端复杂度
|
|
|
|
|
|
|
|
|
|
|
|
设备端是高风险点。
|
|
|
|
|
|
|
|
|
|
|
|
尤其要确认:
|
|
|
|
|
|
|
|
|
|
|
|
- 芯片性能是否支撑 WebRTC
|
|
|
|
|
|
- 是否有硬编 H.264
|
|
|
|
|
|
- 是否支持 Opus / AAC
|
|
|
|
|
|
- 是否支持 TLS
|
|
|
|
|
|
- 是否支持 MQTT 长连接
|
|
|
|
|
|
- 摄像头和麦克风资源是否可同时给 WebRTC 和 AI
|
|
|
|
|
|
- 固件 OTA 是否方便灰度
|
|
|
|
|
|
|
|
|
|
|
|
如果设备 WebRTC 成本过高,建议:
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
第一阶段:设备 -> ZLMediaKit,APP -> ZLMediaKit
|
|
|
|
|
|
第二阶段:中高端设备支持 WebRTC P2P
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 5. BifroMQ 权限和 topic 设计
|
|
|
|
|
|
|
|
|
|
|
|
MQTT topic 一旦上线后修改成本较高。
|
|
|
|
|
|
|
|
|
|
|
|
建议提前确定:
|
|
|
|
|
|
|
|
|
|
|
|
- topic 命名规范
|
|
|
|
|
|
- tenant 隔离
|
|
|
|
|
|
- device 隔离
|
|
|
|
|
|
- session 隔离
|
|
|
|
|
|
- QoS 策略
|
|
|
|
|
|
- retained 使用策略
|
|
|
|
|
|
- LWT 设备离线策略
|
|
|
|
|
|
- ACL 权限模型
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
# 五、上线前必须注意的点
|
|
|
|
|
|
|
|
|
|
|
|
## 1. 安全
|
|
|
|
|
|
|
|
|
|
|
|
必须做好:
|
|
|
|
|
|
|
|
|
|
|
|
- MQTT TLS
|
|
|
|
|
|
- MQTT ACL
|
|
|
|
|
|
- 短期 token
|
|
|
|
|
|
- TURN 临时账号
|
|
|
|
|
|
- ZLM 播放 / 推流鉴权
|
|
|
|
|
|
- 设备密钥不能明文泄露
|
|
|
|
|
|
- 日志脱敏
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 2. 可观测性
|
|
|
|
|
|
|
|
|
|
|
|
至少要能按 `sessionId` 查到:
|
|
|
|
|
|
|
|
|
|
|
|
- 谁发起
|
|
|
|
|
|
- 哪个设备
|
|
|
|
|
|
- 哪个 APP
|
|
|
|
|
|
- 设备是否在线
|
|
|
|
|
|
- invite 是否送达
|
|
|
|
|
|
- accept 是否收到
|
|
|
|
|
|
- offer/answer 是否完成
|
|
|
|
|
|
- ICE 是否成功
|
|
|
|
|
|
- 使用了 P2P / TURN / ZLM / relay 哪条链路
|
|
|
|
|
|
- 失败原因是什么
|
|
|
|
|
|
- 最终状态是什么
|
|
|
|
|
|
|
|
|
|
|
|
否则后期排查会非常痛苦。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 3. 弱网和异常测试
|
|
|
|
|
|
|
|
|
|
|
|
必须覆盖:
|
|
|
|
|
|
|
|
|
|
|
|
- APP 4G / WiFi 切换
|
|
|
|
|
|
- 设备断网重连
|
|
|
|
|
|
- MQTT 断线重连
|
|
|
|
|
|
- TURN 不可用
|
|
|
|
|
|
- ZLM 不可用
|
|
|
|
|
|
- BifroMQ 重启
|
|
|
|
|
|
- `session-orchestrator` 重启
|
|
|
|
|
|
- APP 杀进程
|
|
|
|
|
|
- 设备重复上线
|
|
|
|
|
|
- 双端同时挂断
|
|
|
|
|
|
- 多个 APP 同时呼叫同一把锁
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 4. 资源和成本
|
|
|
|
|
|
|
|
|
|
|
|
需要重点评估:
|
|
|
|
|
|
|
|
|
|
|
|
| 资源 | 风险 |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| TURN | 带宽成本高 |
|
|
|
|
|
|
| ZLMediaKit | 中心转发带宽和 CPU 压力 |
|
|
|
|
|
|
| BifroMQ | 长连接数量 |
|
|
|
|
|
|
| Redis | 会话状态和 TTL 清理 |
|
|
|
|
|
|
| 日志系统 | signaling 和质量上报可能量很大 |
|
|
|
|
|
|
| MySQL | 会话事件写入频率 |
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
# 六、推荐的第一阶段 MVP 范围
|
|
|
|
|
|
|
|
|
|
|
|
第一阶段不要一次性做太满,建议 MVP 范围如下:
|
|
|
|
|
|
|
|
|
|
|
|
## 必做
|
|
|
|
|
|
|
|
|
|
|
|
- `starlock` 创建会话 API
|
|
|
|
|
|
- `session-orchestrator` 独立服务
|
|
|
|
|
|
- BifroMQ 接入
|
|
|
|
|
|
- APP MQTT over WSS
|
|
|
|
|
|
- 设备 MQTT/TLS
|
|
|
|
|
|
- 基础 invite / accept / reject / hangup
|
|
|
|
|
|
- WebRTC P2P 基础链路
|
|
|
|
|
|
- coturn 兜底
|
|
|
|
|
|
- ZLMediaKit 兜底链路
|
|
|
|
|
|
- 基础质量上报
|
|
|
|
|
|
- 基础会话日志
|
|
|
|
|
|
- 事件 worker 回调 `starlock`
|
|
|
|
|
|
|
|
|
|
|
|
## 暂缓
|
|
|
|
|
|
|
|
|
|
|
|
- AI 深度集成
|
|
|
|
|
|
- 自研 media-relay
|
|
|
|
|
|
- 复杂无感切路
|
|
|
|
|
|
- 多区域部署
|
|
|
|
|
|
- 高级网络评分模型
|
|
|
|
|
|
- 全量录像和云存储
|
|
|
|
|
|
- 复杂套餐计费联动
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
# 七、建议的里程碑排期
|
|
|
|
|
|
|
|
|
|
|
|
## 第 1 - 2 周:协议和架构落地
|
|
|
|
|
|
|
|
|
|
|
|
- 确定 API 文档
|
2026-04-27 14:46:21 +08:00
|
|
|
|
- 确定 MQTT topic
|
2026-04-27 14:42:20 +08:00
|
|
|
|
- 确定状态机
|
|
|
|
|
|
- 确定 route 策略
|
|
|
|
|
|
- 确定设备 capability schema
|
|
|
|
|
|
- 搭建 BifroMQ、coturn、ZLM 测试环境
|
|
|
|
|
|
|
|
|
|
|
|
## 第 3 - 6 周:控制面 MVP
|
|
|
|
|
|
|
|
|
|
|
|
- `session-orchestrator`
|
|
|
|
|
|
- `device-bootstrap`
|
|
|
|
|
|
- `starlock` 会话入口
|
|
|
|
|
|
- APP MQTT
|
|
|
|
|
|
- 设备 MQTT
|
|
|
|
|
|
- invite / accept / hangup 跑通
|
|
|
|
|
|
|
|
|
|
|
|
## 第 7 - 10 周:媒体链路 MVP
|
|
|
|
|
|
|
|
|
|
|
|
- WebRTC P2P
|
|
|
|
|
|
- TURN
|
|
|
|
|
|
- ZLM 推拉流
|
|
|
|
|
|
- APP 与设备完整通话
|
|
|
|
|
|
- 失败后切换到 ZLM
|
|
|
|
|
|
|
|
|
|
|
|
## 第 11 - 14 周:稳定性和可观测
|
|
|
|
|
|
|
|
|
|
|
|
- ACK / retry / timeout 完善
|
|
|
|
|
|
- 质量上报
|
|
|
|
|
|
- 会话追踪
|
|
|
|
|
|
- 事件 worker
|
|
|
|
|
|
- 日志和监控
|
|
|
|
|
|
- 弱网测试
|
|
|
|
|
|
|
|
|
|
|
|
## 第 15 - 16 周:灰度上线
|
|
|
|
|
|
|
|
|
|
|
|
- 小范围设备灰度
|
|
|
|
|
|
- 问题收集
|
|
|
|
|
|
- 性能压测
|
|
|
|
|
|
- 回滚方案
|
|
|
|
|
|
- 运维文档
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
# 八、最终建议
|
|
|
|
|
|
|
|
|
|
|
|
这个架构方向是合理的,关键是第一阶段要控制范围。
|
|
|
|
|
|
|
|
|
|
|
|
我建议优先落地这条主链路:
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
APP
|
|
|
|
|
|
-> starlock
|
|
|
|
|
|
-> session-orchestrator
|
|
|
|
|
|
-> BifroMQ signaling
|
|
|
|
|
|
-> 设备
|
|
|
|
|
|
-> WebRTC P2P / TURN
|
|
|
|
|
|
-> 失败后 ZLMediaKit
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
同时把 AI、自研 relay、高级动态选路放到第二阶段。
|
|
|
|
|
|
|
|
|
|
|
|
最需要重点投入的模块是:
|
|
|
|
|
|
|
|
|
|
|
|
1. `session-orchestrator` 状态机
|
|
|
|
|
|
2. BifroMQ topic / ACL / token 设计
|
|
|
|
|
|
3. APP 与设备端 WebRTC 联调
|
|
|
|
|
|
4. ZLMediaKit 弱网兜底
|
|
|
|
|
|
5. 会话日志与问题追踪
|
|
|
|
|
|
|
|
|
|
|
|
如果这 5 个点做好,后续 AI、录像、套餐、计费、多区域扩容都可以逐步叠加。
|