【20年首更】基于声网音视频SDK开发WebRTC2SIP Gateway的思路和步骤,一路填坑走出来的经验分享

目录

1、基于声网的音视频SDK和FreeSWITCH开发WebRTC2SIP Gateway 方案和思路

2、基于声网的音视频SDK和FreeSWITCH开发WebRTC2SIP Gateway报文设计

3、基于声网的音视频SDK和FreeSWITCH开发WebRTC2SIP Gateway 遇到的坑

基于声网的音视频SDK和FreeSWITCH开发WebRTC2SIP Gateway 方案和思路

为什么做这个?

今年初接到一个项目任务,客户要求在自己的音视频平台系统中集成webrtc功能(原系统是基于SIP协议开发的,已经稳定运行多年,已有一定数量的存量客户)。在对比多家RTC产品的效果后,客户对声网音视频DEMO效果后非常满意,指定要求用声网的SD-RTN传输网络,全面改造客户端软件,改善音频通话质量。据客户实测,在某些国家和地区,同样网络环境下比微信的音频通话质量要好很多,比如在东非和中国之间语音通话,延迟很小、声音也更清晰。

目前系统已经上线运行了几个月没出过问题,通话质量也非常好,满足了客户的预期目标。公司要求总结开发阶段中碰到的问题,另外我们也希望能回馈一下社区,形成一个良性互动及不断加强一下社区浓厚的学习交流氛围。有感于这一段时间的开发工作,于是写下这篇文章,我们会在这篇帖子中定期更新,分享开发思路、方案、遇到的问题、解决方法,希望能对大家有所帮助。我会敲代码,不太会表达,如果大家在实现这个模块的过程中也碰到类似的问题,想了解一些细节,欢迎联系回帖提问或者邮箱交流(交流邮箱地址:bd@qzlink.com),咱们尽量答复大家。

一路走来,几个同事经常分析代码到半夜。终于在测试4个月后稳定下来。其实现在回头看,就是因为没有吃透声网的API文档,没有好好利用社区的功能。如果你碰到的坑是跟咱们的类似,那么花点时间仔细撸几遍API文档就可以搞掂了。

话不多说,先列下客户需求:

1、全面改造Android、iOS、Windows、MacOS、Web版5个平台的客户端软件,原来的客户端分别是基于Pjsip、Linphone、Sipjs开发的;

2、要求在网络环境差的地方,也能满足清晰语音通话的要求(声网的音视频实时传输网提供支持);

3、最小侵入性,尽量不改变服务器端的系统功能,实现客户无感升级;

4、解决SIP协议常碰到的丢包、被过滤UDP、无法呼叫和呼叫听不清等问题;

5、解决SIP服务器经常被尝试攻击呼叫、恶意扫描注册攻击等行为,提高系统稳定性;

6、实现WebRTC协议和SIP协议的双向互通,既要兼容SIP呼叫,又支持RTC客户端送呼叫到SIP Server,也要支持SIP Server呼入到客户端软件(在声网的音视频实时传输网传输)。.

其实刚接到需求的时候,大家一起讨论分析过:这种项目看着有不少预算,但是要做全平台客户端,开发任务繁重,要考虑的细节也比较多,没准是个坑,能否达到客户的期望要打一个问号,因此多数同事建议不做。然后在领导和客户一起去happy一晚后,这活儿不知道怎么就接下来了。

老板理由很简单,这也不做那也不做,那我们可以做什么?如果谁都能做,客户还会找我们吗?那就干吧,马上行动,各种查资料,翻阅声网的技术开发文档,并咨询声网的技术同学,2天后拿出初步方案。

系统架构图

解决思路有6步:

1、自己写信令模块,保持灵活性,简单实现。开发TCP Server承担信令服务器;

2、核心是开发一个SIP2WebRTC/WebRTC2SIP协议转换网关,维护一个状态机;

3、开发音视频编解码处理器,解决声网语音和SIP语音编码互通;

4、开发一个状态管理模块,SessionManger,以维护客户端的状态IP和端口;

5、结合声网的音视频SDK,集成自己的信令模块,实现和WebRTC2SIP 模块通讯;

6、自定义常见的SIP呼叫信令,供各平台客户端保持一致。

常用的SIP 信令有:1注册、2呼叫、3接听、4挂断、5拒接、6取消、7Hold、8DTMF、9用户未反映、10用户离线、11Transfer、12会议(我会简单介绍前面的6个)。

PS:我们暂且把这个系统命名为 WebRTC2SIP Connector 或者SIP2WebRTC Connector吧。至于为什么这么叫,我也不知道,可能叫XX Gateway的太多了,不这么叫显不出声网的SD-RTN有多厉害,我是他爹,想叫什么都可以,哈哈

理清思路后,我们需要确认几个核心问题:

  1. 以哪个平台的SDK为基础开发WebRTC2SIP Connector核心模块?

  2. Agora SDK是否支持多并发呼叫?

  3. 声网的语音编码格式和视频编码格式是什么?采样率多少?

  4. SIP客户侧有没有什么具体的编码要求?客户可接受固定一个语音编码,我选择PCMA

这里特别感谢一下声网,对我们这种小众需求做出了快速响应,也感谢声网技术支持同学Nemo,专门来到公司交流了几个小时,并分享了一些技术信息,点一个大大的赞:grinning::grinning::grinning:

声网建议我们:

  1. 用Agora Windows SDK 或者 Linux SDK 开发协议转换模块;

  2. 2个SDK都支持多并发呼叫;

  3. 语音是pcm格式,视频是yuv格式,采样率是48khz;

到这里心里有数了,简要文字描述下大概流程就是:

1、各客户端SDK启动时,发起TCP连接,登录TCP Server信令服务器, WebRTC2SIP转接模块初始化也发起TCP连接登录TCP Server ,由TCP Server记录UID,IP和端口等信息。

2、呼叫的具体流程大概是这样的:

(1)呼叫的时候,申请一个房间号,并根据自定义信令格式发起calling 报文,TCP Server收到后,转发给转接模块WebRTC2SIP ;

(2)WebRTC2SIP收到后创建1个线程,解析报文,并启动声网的SDK,加入指定房间号;

(3)开始读取音频流程,同时启动线程,封装SIP标准报文,发起sip invite请求给电话服务器SIP Server;

(4)SIP Server收到呼叫请求就去呼叫被叫电话号码,并返回ring振铃信号。

(5)WebRTC2SIP收到振铃信号,封装自定义的振铃信息给客户端SDK;

(6)被叫接听后,WebRTC2SIP,启动Media Coder开始解析媒体流,并resample 后,写入到声网的房间里面。实现语音通话。

3、从SIP呼入到声网的SDK,大同小异,反过来就行。

这里要注意:

1、每个终端都要自定义编号;

2、每个呼叫都要加入声网的房间channel 实现音视频互通;

3、因为编码不一样,所以需要resample,这个很重要,不然接通了没有声音,双方不匹配。

4、WebRTC2SIP模块要多线程方式处理,以实现并发呼叫;

5、WebRTC2SIP模块要维护一个完整的状态机,给每个通话加唯一编号,避免出错。

到现在我们讲清楚了大概的解决方案和技术思路,看到这里,各位客官应该明白了,其实这个做起来没啥难度,至少现在看来是这样的。

基于声网的音视频SDK和FreeSWITCH开发WebRTC2SIP Gateway报文设计

上一篇我们提到,常用的SIP 信令有:1注册、2振铃、3呼叫、4接听、5挂断、6取消

有了这几个报文,电话的呼入和呼出就可以基本实现,其他拒接、DTMF等类似。

如图所示:

约定:

  1. 客户端和服务器端JSON格式交互;

必传参数:msgtag 是消息唯一标志,userid是谁触发的,appid 作为一个应用的标记。sign 签名加密 (看情况)

  1. 服务器返回的报文必须包括msgtag \appid\errcode

errcode=1 说明有错误 errmsg就会有值 ,如果errcode=0 说明返回结果正确一般是返回的msgtag 是请求的msgtag+”_res”做为区分

  1. roomID 是房间号,对应声网的渠道号channel ID,每个通话报文必须包括roomID 用途是什么自己想。

  2. callType 是video \ audio前者代表视频呼叫,后者代表语音呼叫

  3. direction 呼叫方向in呼入 (SIP Server 把呼叫送到声网的SDK)out呼出(声网的SDK把呼叫送到SIP Server)

  4. isSIP YES / NO代表这通呼叫是内部呼叫(声网客户端实现) 还是SIP呼叫(走落地)

这篇文章我只是简单列出核心的报文DEMO格式。

信令1:注册报文

响应报文:

信令2:呼叫报文

响应报文:

信令3:振铃报文

响应报文:

信令4:接听报文

响应报文:

信令5:挂断报文

响应报文:

信令6:取消报文

响应报文:

如上图设计的报文非常简单,不需要过多言语说明,供大家参考吧。

后续处理

不论客户端还是WebRTC2SIP Connector本质上都是声网的音视频SDK客户端,然后集成了自定义的信令报文,所以在初始化时,需要调用一个专门的的接口(暂时叫做initSIP),调用这个接口时传递type类型参数。

(1)如果是手机端或者电脑端、网页端调用,返回TCP Server地址和端口,供他们建立TCP连接。

(2)如果是Connector转接服务器请求,除了返回TCP Server地址和端口外,还要返回SIP Serve地址及端口和呼叫送号前缀。不然SDK发起电话呼叫时,Connector不知道电话要转送到哪里。这个开发一个http接口就可以实现。

APP初始化,调用initSIP接口,建立TCP连接,或者呼叫的时候在建立TCP连接;

TCP Server维持所有终端的状态及网络位置做Session Manager角色;

主叫输入的号码编辑封装calling报文,通过tcp socket发给服务器,同时UI呈现拨号等待页面;

被叫收到calling报文,就封装ringing报文,通过tcp socket 发给服务器,服务器查询Session Manager查询主被叫的IP和端口,实现消息的路由转发,主叫收到就显示振铃页面。同时WebRTC2SIP Connector启动Media coder线程去解析和resample读取到的音频流。就这样一个个的报文交互串起来,就可以实现整个SIP呼叫逻辑。

有兴趣的同学,快去试试吧。

(20年首更)3、基于声网的音视频SDK和FreeSWITCH开发WebRTC2SIP Gateway 遇到的坑

前两篇文章我简单介绍了开发WebRTC2SIP的设计架构图和报文逻辑,看着简简单单,做起来还是有很多事情要考虑的。我们在开发的过程中,也是磕磕绊绊,一步一个脚印(坑)走过来的。碰到的很多问题都是兼容的问题。

我们碰到过哪些问题呢?我们总结下来,开发时遇到了这些问题:

1 怎么处理早期媒体?

2 怎么处理加密不被过滤?

3 怎么防止SIP注册攻击和匿名呼叫攻击?

4 怎么支持消息扩展,扩展支持更多服务?

5 正在通话呼叫(calling ringing )过程中,主叫或者被叫断线了,怎么探测?怎么recover,自动重连话务?

6 通话双方任一方突然杀死SDK进程 怎么通知对方?

7 SIP呼入的时候,如果被叫不在线?怎么个处理逻辑?

8 客户要求实现同一个账户同振怎么实现?

9 客户要求支持新版本的的SDK呼入呼出的同时,让同一套账户体系支持SIP的呼入和呼出;如果有人呼入,要求SIP客户端和声网客户端,都要响铃,即要兼容原来的客户固定资产(SIP话机等)可以继续被使用。

除了这些还有在测试阶段发现很多诡异的问题

1、比如电话接通后,说着说着就没声音了,

2、说话会卡断,有时候接通就会卡有的时候通话几分钟后会卡

3、经常碰到被叫挂机,声网的SDK还在写日志,一天50个电话写日志几十G

4、单通,一方听不到声音

5、编码问题,码率不一致

6、各种莫名崩溃:启动崩溃,接通崩溃,挂机崩溃,神经病似得说崩就崩溃。

后面我们会对每个问题进行深入剖析,定期分享我们发现问题-解决问题-总结经验的心路历程。

预告下一篇文章的内容

我们要分享的是解决:早期媒体的处理。

欢迎联系回帖提问或者邮箱交流(交流邮箱地址:bd@qzlink.com),咱们尽量答复大家,也欢迎大家来咱们的官网上看下产品的详细介绍哈:www.webrtc2sip.comwww.fsgui.com

4赞

对webrtc结构不是太了解,学习一下,webrtc媒体处理模块能不能单独拿出来用?如果能分离出来,那么直接替换掉原有Pjsip、Linphone、Sipjs系统中对媒体处理的模块,这样改动应该会少很多吧。

在我们的项目实践中,直接把声网的几个平台的SDK都包了一次,引出了几个方法,最小改动可以快速上线 (正常情况下1天时间内能搞定)。 webrtc2sip模块需要增加一个服务器部署下 ,就是增加了点成本。

这样做的话应该会牺牲一点点性能吧?
不过对你们项目来说应该是最佳方案了。

会有一点性能损耗,但是我认为可以忽略。生产环境单机可支持400多并发(8核16G的,因为客户增加了ASR实时质检,服务器配置高点,这可以满足 95%企业客户需求了)。如果量大可以直接做呼出集群,呼入指定1台机器处理,问题不大。