Angular+Spring集成Jitsi Meet视频通话计时器同步及关闭浏览器回调问题
通话计时器同步方案
- 放弃前端各自维护累加计时的逻辑,所有时间基准完全以后端时间为准:
- 通话状态切换为
initiated时,后端直接生成服务器时间戳作为call_start_time存入数据库,同时同步推送给两个参会端 - 前端仅做时长计算渲染:用校准过服务器时间差的本地当前时间减去
call_start_time得到已通话时长,不需要前端自己做每秒累加的逻辑,从根源避免两边计时偏差 - 要求更高的场景可以每隔30s通过WebSocket主动推送一次后端计算的准确时长,覆盖前端数值,完全杜绝同步误差
- 通话状态切换为
- 也可以配合Jitsi原生的
participantJoined事件,触发时统一拉取后端存储的call_start_time,保证两边计时起始点完全一致。
浏览器关闭时回调可靠触达方案
前端侧优先用专门为页面卸载设计的API保证请求发送:
- 方案1:使用
Fetch API的keepalive属性,支持页面卸载后请求继续后台发送,示例代码:
window.addEventListener('beforeunload', () => { fetch('/api/call/end', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({callId: 你的当前通话ID, userId: 当前登录用户ID}), keepalive: true }); });
- 方案2:使用
Navigator.sendBeacon()接口,浏览器会尽可能保证请求完成,优先级高于普通异步请求,示例代码:
window.addEventListener('beforeunload', () => { const params = new FormData(); params.append('callId', 你的当前通话ID); params.append('userId', 当前登录用户ID); navigator.sendBeacon('/api/call/end', params); });
前端方案无法覆盖所有极端场景(比如浏览器进程崩溃、设备突然断网断电),必须增加后端兜底逻辑:
- 新增定时任务(Spring项目可以直接用
@Scheduled注解实现),每分钟扫描所有状态为initiated的通话记录,对比当前时间和call_start_time的差值,如果超过业务设置的最长通话阈值(比如2小时),自动将状态改为call_end,按照阈值时长或Jitsi侧记录的实际会议结束时间计算费用;多实例部署时要加分布式锁,避免同一通话被重复处理 - 对接Jitsi Meet服务端回调,Jitsi本身支持配置会议结束、参会人全部离开的服务端回调事件,只要Jitsi服务端检测到会议终止,就会主动请求你的后端接口更新状态,是最可靠的兜底手段。
内容的提问来源于stack exchange,提问作者peralta11
相关产品推荐
相关产品推荐

