Files
lxc-streamutils/docs/components/README.md
T
2026-07-16 00:12:26 -07:00

59 lines
3.4 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.
# 组件开发指南
组件是“一个直播源上的独立功能实例”。当前内建
`danmaku_overlay`,未来礼物墙、点歌姬或统计组件都应使用同一套契约。
## 一个组件由什么组成
| 部分 | Rust 契约 | 职责 |
| -------- | --------------------- | ------------------------------------------------- |
| 定义 | `ComponentDefinition` | kind、设置版本、默认值、校验、迁移、订阅 |
| 投影 | `EventProjection` | 把 `LiveEvent` 转成浏览器消息,不执行持久化副作用 |
| Handler | `EventHandler` | 可选的数据库写入、点歌或外部动作 |
| 实例 | `ComponentInstance` | owner、source、kind、名称、设置和启用状态 |
| 实时通道 | `EventHub` | 按 component ID 隔离的有界广播 |
| 前端 | React renderer/editor | 管理设置、测试与 OBS 展示 |
## 新增组件步骤
1. 选择稳定、全小写的 kind,例如 `gift_wall` 或 `song_request`。
2. 为设置定义可序列化结构,提供安全默认值和 `sanitize`/校验逻辑。
3. 实现 `ComponentDefinition`:
- `settings_version` 从 `1` 开始。
- `migrate_settings` 必须能把已保存的旧版本升级到当前版本。
- `subscriptions` 只返回当前设置需要的 `LiveEventKind`。
4. 实现无副作用的 `EventProjection`。返回 `None` 表示该事件无需发送浏览器。
5. 若需要可靠业务动作,实现 `EventHandler`:
- 即使没有 OBS 客户端也会执行。
- 数据库操作必须包含 owner/source/component 条件。
- 上游可能重试或出现组合事件,因此 handler 自己负责幂等。
6. 在 `ComponentRegistry::with_builtin_components` 注册定义与投影,再注册 handler。
7. 增加数据库创建/设置 API;不要把组件专属关系数据无限塞入 JSON settings。
8. 在控制台增加设置编辑器,在 OBS 前端增加对应事件渲染器。
9. 增加以下测试:设置边界、版本迁移、订阅、跨租户拒绝、handler 幂等、投影 wire shape 和 OBS 渲染。
## Projection 与 Handler 的边界
Projection 面向“现在打开的浏览器”。消息丢失或没有接收者都属于正常情况。它必须快速、确定、无副作用。
Handler 面向“业务事实”。例如点歌请求、礼物累计或审计写入必须在这里完成,而不是等待前端收到 WebSocket。一个 handler 失败会记录在
`RouteReport`,但不会阻止其他 handler 或 OBS 投影。
## 设置版本规则
- 数据库同时保存 `settings` 与 `settings_version`。
- 每次读取或路由前,通过 registry 迁移并校验设置。
- 新字段应提供默认值,删除/改义字段必须增加版本并编写迁移。
- 客户端输入只能作为待校验 JSON;后端返回的 sanitized 设置才是权威值。
- UI slider 的范围不能代替后端范围检查。
## 租户与 token 规则
- 组件必须属于同一个 owner 与 source。
- 路由和数据库查询都要重复检查这一关系。
- 每个组件单独签发 access token,默认只有 `events:subscribe`。
- 删除组件或轮换 token 时,关闭该组件 channel,使已有 socket 立即失效。
- 组件 WebSocket 不得暴露其他组件列表或控制 API。
当前组件的具体行为见 [`danmaku-overlay.md`](danmaku-overlay.md)。