验证状态:存在关键缺口,不可作为完整契约发布。Web 发送、应答消费、WebRTC 协商与恢复链已源码核验;设备固件是
device/{deviceNo}/webrtc/v1的最终消费者,其 SDP/ICE 候选载荷的权威字段与错误形态缺证。 适用基线:源码归纳 @ 2026-09-14
设备直播状态为 idle(或本会话已占用)时,Web 通过四个信令命令与设备直接协商 WebRTC 媒体流(不经 Janus):call 发起呼叫并换取设备 offer,sdp 回传 Web answer,candidate 双向交换 ICE 候选,bye 在卸载时挂断。本页是这四个操作的唯一操作正本。状态判定与占用语义见 探测设备直播状态与媒体配置;SFU(Janus)分支见 Janus 直播会话。
| 页面/功能 | 角色或空间分支 |
|---|---|
| P2P 直播组件挂载即呼叫 | 登录用户;播放器分派到 P2P 分支 |
| 同组件:回传 answer、上行候选、卸载挂断 | 同上 |
| 播放器检测到 P2P 被占用/过渡态时抢占重呼 | 同上 |
对应 inventory operationId:mqtt-player1-device-var-webrtc-v1-6fddc476(call,两个调用点同载荷)、mqtt-sdpfn-device-var-webrtc-v1-2f1bfcd8(sdp)、mqtt-candidatefn-device-var-webrtc-v1-c7837c94(candidate)、mqtt-webrtclivep2p1-device-var-webrtc-v1-8b56ff3c(bye)。
MQTT 发布 device/{deviceNo}/webrtc/v1(Web ⇄ Broker ⇄ 设备直连,中心网关不消费;QoS/retain 等 wire 细节见业务页)— call / sdp / candidate / bye 四个 P2P 信令命令。
设备直连 webrtc 通道属中心不消费的接入面(网关默认订阅清单无 device/+/webrtc/#,见服务端订阅面);通道业务语义见设备业务 · mqtt-bridge 设备消息链。载荷形态 {sub, id, reply[, params]}(bye 无 reply);设备应答以 sub 字段分类(sdp/candidate),无 transaction 关联,应答回流到请求 reply topic。
| 层级 | 判据 |
|---|---|
| 发布完成 | publishAsync Promise 成功;不代表设备收到或执行 |
| SDP 确认 | reply topic 收到 sub:"sdp" 应答且非空 |
| 媒体就绪 | RTCPeerConnection.connectionState === "connected";ontrack 收到远端轨道并绑定 video |
| 超时/重试 | 呼叫后 15 秒仍无 SDP → retryConnection(500ms 间隔复查);连接失败/断开 15 秒后 → retryConnection;重试由播放器清空 pong 重新探测 |
| 挂断 | 组件卸载即 byeFn + 停轨 + 关闭 PeerConnection;bye 无应答等待 |
Web 收到 sub:"sdp" 后的协商链(已核验):setRemoteDescription(offer) → createAnswer → sdpFn 发布 answer → setLocalDescription(answer);ICE:Web 本地候选经 onicecandidate → candidateFn 上行,设备候选等待 remoteDescription 就绪后加入(10ms 轮询、30 秒上限)。
call/sdp 均无传输层失败终态;设备离线或不响应时页面停留在"等待设备响应 sdp"计时文案。pong.status="p2p" 且 data.id 非空且非本会话;id 为空的过渡态由持续 call 推动设备恢复。getUserMedia audio + 回声消除/降噪/增益),采集失败仅记日志并继续接收视频。sdp/candidate 乱序由 waitFor(remoteDescription) 缓冲。pong 判定 + list-ice-server 正本 的 ICE 配置(为空时组件等待)。bye → 停麦克风/远端轨道 → PeerConnection.close → 清空队列。pong.status 变化驱动播放器重挂载。bye 后设备状态迁移均缺证。