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

4.1 KiB
Raw Blame History

组件实时协议

当前协议版本为 1。后端的权威定义在 domain.rs 的 ComponentMessage,浏览器渲染器只依赖本文列出的稳定字段。

连接地址与认证

组件流地址:

wss://danmaku.luoxingci.com/api/v1/components/<publicId>/stream

OBS 页面地址中的 token 位于 fragment:

https://danmaku.luoxingci.com/obs/<publicId>#token=<component-token>

fragment 不会进入首次 HTTP 请求或 Nginx access log。WebSocket 建立后,客户端必须在 8 秒内发送第一帧:

{
  "type": "authenticate",
  "token": "component-token"
}

服务端验证 token 摘要、组件归属和 events:subscribe scope。认证成功后返回:

{
  "version": 1,
  "type": "authenticated",
  "componentId": "08d31d19-3e4b-4c11-9cf7-9bd786a39465"
}

之后立即发送 overlay.settings.snapshot,再开始发送实时事件。token 无效、被轮换或属于其他组件时,服务端以 policy close 结束连接。

版本化事件信封

{
  "version": 1,
  "id": "d56c1a28-a6f1-4ad9-b02f-4c22dc4d3c27",
  "componentId": "08d31d19-3e4b-4c11-9cf7-9bd786a39465",
  "sourceId": "c8087bb0-0dde-40eb-a43d-a9a2574c2717",
  "occurredAt": "2026-07-15T20:10:30.125Z",
  "roomId": "123456",
  "type": "live.danmaku",
  "payload": {
    "viewer": { "uid": "42", "name": "观众" },
    "text": "晚上好",
    "segments": [{ "type": "text", "text": "晚上好" }]
  }
}

ownerId 永远不会序列化到浏览器。消费者应按 version 和 type 分派,并忽略不认识的 payload 字段,从而允许兼容地增加元数据。

事件类型

type 主要 payload 说明
overlay.settings.snapshot settings 认证后当前设置快照
overlay.settings.updated settings 控制台保存后的实时设置
live.danmaku viewer, text, segments 普通文字和表情分段
live.enter viewer 进房事件
live.gift viewer, gift, quantity, sourceEventId 一次可记账的礼物事件
live.gift.combo viewer, gift, quantity, comboId 同一连击的视觉更新
live.superchat viewer, message, price, sourceEventId 醒目留言
live.guard.buy viewer, guardName, quantity, price 舰长购买
live.like viewer 点赞
live.share viewer 分享
live.unknown command, metadata 有界且已清理的未知事件

礼物目录价格的原始单位是人民币的千分之一。gift.totalPrice 保留该整数单位,gift.priceCny 是供展示使用的人民币数值。

live.gift 与 live.gift.combo 不是两笔礼物。需要持久化计数的组件通常只消费 live.gift;连击事件用于更新同一张视觉卡片。

表情分段

live.danmaku.payload.segments 是判别联合:

  • text:包含可直接显示的文字。
  • emoticon:包含回退文字、图片 URL、可选尺寸、动态标记和整条大表情标记。

图片失败时客户端必须回退到 text,不能让一张失效图片破坏整条弹幕。

背压与重连

  • 每个组件使用有界 tokio::broadcast channel。
  • 慢客户端发生 Lagged 时跳过已经丢失的旧帧,继续接收新事件;实时展示不保证历史重放。
  • 浏览器对非鉴权关闭使用指数退避重连,上限 12 秒。
  • 鉴权失败不会自动重试,避免对已撤销 token 形成无限请求。
  • 需要可靠业务处理的功能必须实现 EventHandler 并写入数据库,不能把 WebSocket 当作消息队列。