RTC引擎切换项目一些思考

216 阅读4分钟

前言

因现有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, 以支持客户端灰度降级

image.png

基于抽象工厂模式, 实现两个工厂,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接口改造

image.png

  • 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版本时,可以正确切线