尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

从 Mesh WebRTC 到 LiveKit SFU:在线考试监考大屏实战

从 Mesh WebRTC 到 LiveKit SFU:在线考试监考大屏实战 适用场景在线考试监考大屏、一对多实时视频观看、业务信令与媒体分离一、背景为什么要换掉 Mesh WebRTC早期监考方案常见做法是 Mesh WebRTC考生与监考之间两两建联走 SDP Offer/Answer ICE Candidate。考试场景下问题很明显连接数爆炸N 个考生 × M 个监考 ≈ O(N×M) 条 PeerConnection考生上行压力大同一路摄像头可能被多台监考电脑同时拉流信令复杂Offer/Answer/Candidate 与业务消息混在一起重连、黑卡、多端登录难维护监考多电脑同一老师账号开两台大屏时会话互踢或名单不同步我们把媒体层升级为 LiveKit SFU业务层仍走自有 WebSocket目标是考生端只推摄像头publish-only监考大屏只订阅观看subscribe-only不采集本地摄像头同账号多台电脑可同时监考Token 续签 意外断线自动重连支撑长考试二、整体架构核心原则媒体走 LiveKit业务走 WebSocket。通道职责典型消息LiveKit音视频转发TrackSubscribed / ParticipantDisconnected业务 WebSocket名单、作弊、喊话、强交examineeJoined/examineeLeft/examineeCheat不再传输 SDP / ICE。三、房间与 Identity 约定约定一旦定好前后端都按它解析少踩坑。1. 房间名exam_{examId}一场考试一个房间固定命名便于考生关浏览器再进考时回到同一房间。2. Identity角色Identity权限考生stu_{userId}canPublishtruecanSubscribefalse监考inv_{userId}_{clientId}canPublishfalsecanSubscribetrue说明考生 identity 一人一场固定大屏用stu_前缀反解userId绑定视频卡片监考 identity 带 clientId前端对登录 token 做 MD5同账号多电脑 多个 Participant互不踢大屏反解考生 ID 的逻辑很简单四、后端签发 LiveKit JWTLiveKit 进房靠 Access Token标准 JWT。Java 侧可用 Auth0 JWT 自行签发不必强依赖官方 Java SDK。1. 配置2. Token 里的关键授权关键是videograntJWT 字段要点iss api-keysub identityvideo 上述 grantexp now ttl返回给前端的 VO 建议带上tokenTtlSeconds方便客户端提前续签3. userJoin登记会话 发凭证监考加入时Redis 写入(userId, clientId)会话24h TTL签发监考 Token返回当前考生名单examineeList大屏先画卡片再等视频轨考生加入时Redis 登记在线考生签发考生 Token向所有监考推送examineeJoined媒体由 SFU 自动转发这里只同步业务名单五、考生端publish-only 推流依赖livekit-client思路页面先getUserMedia拿本地预览抓拍、行为检测共用一路userJoin拿 TokenRoom.connect后用LocalVideoTrack包装已有轨 再publishTrackautoSubscribe: false不订阅任何人关键片段这样续签/重连时只重进 LiveKit不会反复弹摄像头权限。六、监考大屏subscribe-only 订阅大屏是本文重点流程如下。1. 启动顺序很关键先有卡片再等轨。否则TrackSubscribed到来时找不到用户对象。2. Room 封装要点3. 视频绑定优先track.attach比手动srcObject更稳组件销毁时记得detach避免 DOM/轨绑定泄漏。4. 大屏绝不采集摄像头订阅端不调用getUserMedia浏览器不会弹摄像头权限——这是监考场景的体验红线。七、异常离场怎么清「黑卡」又不误伤重连考生关浏览器时LiveKit 会触发ParticipantDisconnected。若立刻删卡片考生马上重进考会出现闪烁甚至误清。我们采用 两段延迟 世代号约 600ms清空画面卡片还在约 5s仍未重连出流 → 移除卡片并调后端markExamineeLeft清 Redis同时给每个考生维护trackEpoch每次成功绑定新轨trackEpochdisconnect 时记下当时的 epoch若确认清卡前 epoch 已变说明中间又出流了→ 取消清卡伪代码交卷后的历史作弊记录回填时要用createIfMissingfalse避免「造黑卡」。八、Token 续签与意外断线重连1. Token 续签默认 TTL 2 小时到期前约 5 分钟再调userJoin拿新 Token主动 disconnect 旧房标记lkIntentionalDisconnectconnect 新房并重新订阅/推流失败则 60 秒退避重试2. 意外彻底断线livekit-client对短暂抖动有内置重连业务层关心的是RoomEvent.Disconnected已彻底离房。注意主动 disconnect 也会触发 Disconnected必须用标志区分考生端、监考端都建议做同一套rejoinLiveKit长考 弱网才稳。九、同账号多电脑监考关键点在 clientIduserLeave只删本端 session不影响另一台电脑。路由离开时也要调userLeave不要只断 LiveKit否则 Redis 会残留beforeunload请求可能被浏览器掐掉靠会话 TTL 兜底。十、端到端时序监考大屏视角十一、踩坑清单进房补扫先开大屏再进考生没问题先有考生再开大屏必须emitExistingTracks否则黑屏。ParticipantConnected 后延迟再扫一次订阅完成可能略晚于 connected。续签会批量 disconnect本端换票时远端事件会误触发清卡必须用tokenRenewing屏蔽。joinInvigilateInflight成功后要 finally 释放否则 WS 重连不会再userJoin。包装本地轨时用userProvidedTracktrue否则 disconnect 会把页面预览摄像头 stop 掉。wss / api-secret 不一致连接失败优先查 LiveKit URL 是否浏览器可达、密钥是否与livekit.yaml一致十二、小结这套方案的本质是用 LiveKit 解决一对多实时视频用业务 WebSocket 解决考试语义用 Identity/clientId/世代号解决重连与多端。相对 Mesh收益是考生只推一路监考数量线性扩展大屏零摄像头权限、接入简单信令变薄重连/清卡/多端可测可控如果你也在做「监考大屏 / 教室巡课 / 一对多看监控」类产品优先考虑 SFU 业务信令分离而不是继续堆 PeerConnection。参考LiveKit Docslivekit-clientJSLiveKit Access TokenJWT video grant
返回列表