对讲房间主动事件(participantsChanged / participantLeft / trickle / sessionTerminal / livenessProof)

验证状态:已源码核验、未联调;适用基线:源码归纳 @ 2026-09-14

用途与场景

Janus 主动推送到对讲房间 reply topic 的事件族:成员变化、成员离开、远端 ICE 候选、会话终止与存活证明。本页是 5 个事件 operationId 的唯一正本:mqtt-janus-audiobridge-event-participantschanged-event-participantleft-event-trickle-event-sessionterminal-event-livenessproof。这些事件没有请求方 transaction,中心按会话路由缓存定向转发;Web 在客户端内部把它们归一化为 5 类事件供房间状态机消费。

使用位置

页面/功能 角色或空间分支
对讲房间 Janus 客户端注册监听并分发 audiobridge 事件(事件消费驱动成员列表/恢复状态机/存活证明) 登录用户;已建立会话

端点

MQTT 订阅 user/{username}/web/{sessionId}/talkgroup/{talkGroupId}/janus(Janus 主动推送,无请求方 transaction)— 5 类房间事件:participantsChanged / participantLeft / trickle / sessionTerminal / livenessProof。

回包与事件的定向路由(session 路由缓存、transaction 前缀)契约见 MQTT 主题清单 · 动态下行;janus 转发链的业务语义见设备业务 · mqtt-bridge 设备消息链。事件字段全集无 schema 真源(Janus 源码不在工作区),下方事件契约为 Web 侧已核验的解析与消费口径。

事件契约(Web 侧已核验的解析与消费)

participantsChanged(mqtt-janus-audiobridge-event-participantschanged

字段 类型 条件 说明
janus string "event"
session_id / sender number sender 必须匹配当前 handle 路由过滤
plugindata.data.participants array 存在即触发 成员全量列表
plugindata.data.resumed number/string 存在时 kind="resumed",否则 "merge" 恢复/合并语义

Web 消费:以 {type:"participantsChanged", participants, kind} 事件更新成员列表。

participantLeft(mqtt-janus-audiobridge-event-participantleft

字段 类型 条件 说明
plugindata.data.leaving number/string 存在即触发 离开者参与者 ID

Web 消费:{type:"participantLeft", janusParticipantId},按 ID 移除成员。

trickle(mqtt-janus-audiobridge-event-trickle

字段 类型 条件 说明
janus string "trickle"
candidate unknown 远端 ICE 候选(含 completed 收尾形态,未字段级核验)

Web 消费:{type:"trickle", sessionId, handleId, candidate},交给浏览器会话添加远端候选。

sessionTerminal(mqtt-janus-audiobridge-event-sessionterminal

字段 类型 条件 说明
janus string timeout/destroyed/hangup/detached/error(458)/插件 left/destroyed/失败
error.code number 458 时 会话不存在

Web 消费:{type:"sessionTerminal", origin: core|plugin|timeout|hangup|detached|destroyed, code?, reason?};驱动恢复状态机(可重试则自动重连,不可重试则失败态)。会话未创建期的无 session_id 458 也按终止处理。

livenessProof(mqtt-janus-audiobridge-event-livenessproof

不是独立 wire 事件:任何属于当前会话/在途事务的回包或事件都会重置 keepalive 等待并发出 {type:"livenessProof", sessionId}。Web 消费:确认 20 秒存活窗口(JANUS_LIVENESS_DEADLINE_MS)。

动线与完成判据

层级 判据
事件送达 topic 命中当前会话且通过 handle 过滤(sender==handleId 或会话级事件)
事件丢失 无补发机制:快照兜底靠 listparticipants 正本 周期轮询与 join/leave 回执中的成员数组
乱序/重复 resumed/merge 区分恢复语义;成员列表以最近事件+快照收敛

错误与边界

  • 路由缓存未命中(会话从未有过带 transaction 的应答、或缓存被新客户端覆盖)→ 事件被中心丢弃,Web 无感知。
  • Web 对不属于当前会话/句柄的消息全部忽略(hasCurrentSessionsender 过滤),跨会话串扰被抑制。
  • 断线重连后:MQTT 重订阅恢复投递;断线窗口内的事件丢失靠快照与 join 回执收敛,不做补发。
  • 存活判定:20 秒无任何会话回包/事件 → 失活,触发恢复(周期 keepalive 每 20 秒,见 会话生命周期正本)。

调用关系与资源清理

  • 与请求族的关联:应答路由建立会话绑定;事件依赖该绑定。
  • 监听清理:subscribe 返回退订函数;最后一名订阅者与在途请求消失时摘除 emitter 监听(stopListeningIfIdle)。

已知缺口

  1. Janus 插件事件的字段全集(participants 元素、resumed 取值、audiobridge 事件名)源码不在本工作区;本页记录 Web 消费判据而非插件字段全集。
  2. 事件乱序、重复与 Broker QoS 行为未做真实联调核验。