前言
因现有RTC引擎(开源WebRTC)在使用过程中,稳定性堪忧,经常出现建连失败的问题,团队经过调研决定切换到AgoraRTC
挑战
- OldRTC加入NewRTC房间时,实现顺滑切线
- 重构端逻辑,支持快速接入新RTC-SDK
- 支持灰度/ 强制WebRTC/ 强制AgoraRTC
- 稳定性建设:构建RTC指标体系,链路监控,报警机制(本篇不涉及)
切线调研
切线是新老版本RTC通话过程重要流程,但切线对用户体验有一定影响,为降低切线概率,基于切线场景梳理,产品与技术出台如下方案
切线场景梳理
| 场景 | 方案 |
|---|---|
| UserA(WebRTC)---> UserB (WebRTC+MmcRTC) | 使用WebRTC建立会话 |
| UserA(WebRTC+MmcRTC)---> UserB (WebRTC) | 使用WebRTC建立会话 |
| User(WebRTC+MmcRTC)---> Session(WebRTC) | 使用WebRTC接入会话 |
| User(WebRTC)---> Session(MmcRTC) | Session触发切线,建立WebRTC新会话 |
| User(WebRTC+MmcRTC)---> Session(MmcRTC) | 使用MmcRTC接入会话 |
产品侧
- 当仅当新RTC版本覆盖率大于90%时允许放开灰度
- 一次会话过程仅允许切线一次(降级后此次通话仅会在低版本RTC版本进行,不会再升级)
技术侧
- 当仅当信令房间支持NewRTC且端支持NewRTC时,端使用NewRTC建连
- 收到切线信令时,OldRTC建连与NewRTC断连任务并行执行
端逻辑重构
抽象逻辑可应用于三端
现有逻辑梳理
XCall模块逻辑代码目前有分层设计,但无法满足SDK快速切换,需进一步抽象改造接口
- CallLogic: 主要处理UI与Session交互逻辑,包括UI刷新,是否允许建立会话等逻辑,可复用,但需进一步抽象ICallSession支持切换CallSession与IntegratedCallSession
- CallSession: 主要处理CallLogic与WebRTC/WebSocket交互逻辑,包括WebSocket建连状态回调,WebRTC建连状态回调等,可复用,但为支持客户端可灰度降级,新增IntegratedCallSession,全量稳定运行后可去除CallSession
- CallSessionConnectionWrapperManager: 主要处理CallSession与WebRTCConnection交互逻辑,包括创建WebRTCConnection,ice过程处理等,不可复用,需抽离接口,实现MmcRTCConnectionWrapperManager
- WebRTCConnectionWrapper: 主要处理WebRTC事件回调以及RTC连接状态管理等,与CallSession有部分交互逻辑,不可复用,无需抽离接口,需新增MmcRTCConnectionWrapper
接口抽象与改造
CallSessionFactory接口改造
目标:支持根据入参构造不同的ICallSession, 以支持客户端灰度降级
基于抽象工厂模式, 实现两个工厂,ICallSessionFactory – ICallSession – CallSessionContext 接口与实现一一对应,并单向引用
ICallSessionFactory: 抽象工厂接口
- DefaultCallSessionFactory: 默认实现,用于构造原有逻辑的CallSession
- IntegratedSessionFactory: 支持MmcRTC能力的实现,当CallLogic使用IntegratedSessionFactory时,构造IntegratedCallSession
ICallSession: 抽象会话接口
- CallSession: 工程原有类
- IntegratedCallSession: 支持WebRTC与MmcRTC的ICallSession,支持WebRTC与MmcRTC的切线,可基于信令事件确定使用使用WebRTC or MmcRTC
CallSessionContext: 聚合业务参数,基于不同的CallSession派生不同的CallSessionContext
- DefaultCallSessionContext: 核心参数session,token,callback等
- IntegratedCallSessionContext: 目前参数和DefaultCallSessionContext没有差别,后续可新增vendor参数用于指定MmcRTC线路
SessionRTCConnectionManager接口改造
- ICallSession引用ISessionRTCConnectionManager(新抽象接口),Manager引用RTCConnectionWrapper
- IntegratedCallSession需支持WebRTC与MmcRTC,所以需持有ISessionRTCConnectionManager的两个不同实现
- RTCConnectionWrapper无需抽象接口,由不同的ISessionRTCConnectionManager实现进行构造即可
基于重构代码接入新SDK
若需支持灰度,继承实现ICallSessionFactory即可,新RTC需继承实现SessionRTCConectionManager接口,并实现相应回调接口即可快速接入新SDK
思考
第一次主导一个中型技术项目,作为AndroidDev,以往的技术调研及方案设计往往局限于Android技术栈,但作为技术Owner,技术方案的设计必须要考虑跨端可行性,端到端可行性,方案是否是最优的,实现成本较低的,都是一个技术Owner需要思考的事情 举个例子,如果切线方案不考虑多端响铃,一端接入的场景,那么会导致信令房间RTC版本信息错误(PC支持OldRTC,Mobile支持NewRTC,UserX同时在PC/Mobile登录) 举个例子,服务端切线信令协议的设计,应覆盖仅支持OldRTC,支持OldRTC+NewRTC,仅支持NewRTC等,便于后续线上存在多个RTC版本时,可以正确切线