交换 ICE 候选(VideoRoom trickle)

验证状态:已源码核验、未联调;Web 发送/消费与中心双向路由已双侧核验;Janus 侧候选事件字段缺证。 适用基线:源码归纳 @ 2026-09-14

用途与场景

Web 与 Janus 之间的 ICE 候选双向交换:Web 本地候选经 trickle 上行;Janus 侧候选以无 transaction 事件到达 Web 回包 topic,Web 取其顶层 candidate 加入连接。公共口径见 会话正本

使用位置

页面/功能 角色或空间分支
SFU 直播组件 onicecandidate 经串行队列发布 trickle 登录用户;PeerConnection 已建立
同组件消费下行候选并加入 PeerConnection 同上

对应 inventory operationId:mqtt-janustricklefn-server-center-server-iot-v1-forward-janus-to-b0f0a8e3

端点

MQTT 发布 server/center-server/iot/v1/forward/janus/to(Janus 侧候选经物理入站按 session 路由回流)— trickle 请求,上行 Web 本地 ICE 候选;下行候选为无 transaction 事件。

通道契约全量事实见 MQTT 主题清单 · 静态 topic动态下行谓词族(janus 物理入站正则);字段级契约见 yaml 详解 · forward-janus-to;janus 转发链业务语义见设备业务 · mqtt-bridge 设备消息链。上行请求报文 {janus:"trickle", candidate, handle_id, transaction, session_id},transaction suffix 为 trickle;下行形态为无 transaction 事件、顶层含 candidate 对象(candidate.completed 为真时 Web 忽略),中心按 session_id 查会话路由缓存归还。

动线与完成判据

  • 上行发布完成 = publishAsync 成功;无应答消费。
  • 候选交换整体完成的判据是 connectionState==="connected";无候选级超时。
  • 下行候选消费前提:remoteDescription 已设置(waitFor 10ms 轮询、30 秒上限);加入失败仅记状态文案。

错误与边界

  • Janus 无候选下发(如媒体通道未建立)时,Web 等待连接超时路径兜底;无独立失败出口。
  • 下行候选先于 SDP 到达时由 waitFor(remoteDescription) 缓冲 30 秒,超时后该候选丢失(无补发)。
  • 回环与非法 transaction 的中心丢弃同 会话正本;无 transaction 且查不到 session 绑定的事件被中心丢弃。

调用关系与资源清理

  • 时序:join SDP → starttrickle 交织 → connected
  • 候选队列随组件卸载清空(outputQueue.clear():509-511);PeerConnection 关闭后 onicecandidate 不再触发。

已知缺口

  1. Janus 下行候选事件(janus:"trickle" 事件形态、completed 语义、candidate 字段全集)源码不在本工作区;本页记录 Web 解析期望。
  2. 未执行真实 Broker/Janus 联调;ICE 服务器配置见 list-ice-server 正本