mediasoup create/connect WebRtcTransport 流程分析
一. 前言
在这篇博客中我们介绍了 mediasoup-demo 启动流程与信令交互,关键信令包括 getRouterRtpCapabilites,join, createWebRtcTransport, connectWebRtcTransport, produce,本文将介绍 createWebRtcTransport 和 connectRtcTransport 的流程。
二. createWebRtcTransport
mediasoup-demo 信令层接收到 createWebRtcTransport 消息后处理请求参数并作为 webRtcTransportOptions 传递给 mediasoup C++ 层创建 transport 使用,请求参数包括 { forceTcp, producing, consuming, sctpCapabilities }。
mediasoup Router 接收到 ROUTER_CREATE_WEBRTC_TRANSPORT 请求后创建 RTC::WebRtcTransport 对象。
WebRtcTransport 构造函数处理流程如下,首先获取 enableUdp, enableTcp, preferUdp, preferTcp 参数配置,如果 enableUdp=true 则返回的候选者地址列表包含 UDP 类型的 (ip, port),如果 enableTcp=true 则返回的候选者地址列表包含 TCP 类型的 (ip, port),preferUdp=true 表示更倾向于使用 UDP,preferTcp=true 表示更倾向于使用 TCP,倾向性体现在候选地址的优先级。
如果 enableUdp 和 enableTcp 同时为 true,说明需要返回两种协议类型的候选者列表,因此 iceCandidates 的大小设置为 listenIps 的 2 倍,每个 iceCandidates 对应一个 UdpSocket 或者 TcpSocket。UdpSocket 底层是 libuv 的 uv_udp_t 对象,它会在收到 UDP 报文数据后回调 WebRtcTransport 的 OnUdpSocketPacketReceived 处理,TcpSocket 底层则是 libuv 的 uv_tcp_t 对象。
候选者的优先级计算规则为:
icePriority = 2^24 * IceTypePreference + 2^8 * localPreference + 2^0 * (256 - IceComponent)。
IceTypePreference 为固定值 64,IceComponent 为固定值 1,说明 icePriority 与 localPreference 成正相关关系,
localPreference = IceCandidateDefaultLocalPriority - iceLocalPreferenceDecrement,
IceCandidateDefaultLocalPriority 为固定值 10000,而 iceLocalPreferenceDecrement 每次计算完一个地址列表后都会自增 100,也就是地址列表中靠后的地址优先级低于靠前的地址,并且如果设置了 preferUdp 或者 preferTcp 相应类型的候选者 localPreference 会加上 1000。
WebRtcTransport 构造函数最后创建 ICE Server 和 DTLS Transport 对象。
ICE 称为交互式连通建立方式(Interactive Connectivity Establishment)。ICE 有两种类型,一种是 full ICE,这种方式通信的双方都要进行连通性检查,另一种是 lite ICE,这种方式 lite ICE 方只要被动回应 reponse 消息即可,即 lite ICE 端不需要主动进行连通性检查,只要 full 端完成连通性检查即可,ICE Server 对应 lite ICE 实现。
DTLS 是 UDP 层的安全传输协议(类似于 TLS),用来交换 SRTP 加解密的密钥。mediasoup 在启动时会读取配置的证书文件,然后为证书生成不同的散列值(指纹),在验证证书有效性时就可以比对指纹,如果指纹相等说明下发的证书没有被修改过。
transport 创建完成后,信令层会监听 C++ 层发送的 sctpstatechange, dtlsstatechange, trace 事件并作出相应处理。
createWebRtcTransport 最后返回 { id, iceParameters, iceCandidates, dtlsParameters, sctpParameters }。
字段 | 含义 |
id | 传输通道id |
iceParameters | ICE类型,ICE用户名,密码 |
iceCandidates | ICE候选者信息,包括ip, 端口, 协议类型, 优先级等信息 |
dtlsParameters | 用于DTLS握手的证书指纹信息 |
sctpParameters | SCTP配置信息 |
客户端在收到 createWebRtcTransport 的返回结果后会开启媒体连通性检查,即对 ICE candidates 列表地址发送 STUN 包 binding request ,mediasoup 收到后回应 binding response,如下是抓包内容。
STUN 报文头部如下所示,Message Type 表示消息类型(包含 Message Method 和 Message Class),Message Length 表示 STUN 消息长度,不包含 20 字节头部,Magic Cookie 值固定为 0x2112A442,Transaction Id 为事务 ID,用于请求和响应的标记 ID 号。RFC3489 定义了 128 bit 的事务 ID,而 RFC5389 将 128bit 的事务 ID 分成 32bit 的 Magic Cookie 和 96bit 的 Transaction Id,因此根据 Magic Cookie 值可以区分是 RFC3489 还是 RFC5389 的 STUN 协议。
STUN 报文头部后面跟着 0 个或多个属性(attribute),每个属性都采用 TLV 格式编码。
Type | 属性 | 含义 |
0x0001 | MAPPED-ADDRESS | 获取客户端映射后地址 |
0x0006 | USERNAME | 通知用户名 |
0x0007 | PASSWORD | 密码,用于安全认证 |
0x0008 | MESSAGE-INTEGRITY | 消息完整性,包含一段SHA-1散列值 |
0x0009 | ERROR-CODE | 错误码类型 |
0x000A | UNKNOWN-ATTRIBUTES | 未知属性 |
0x0020 |
XOR-MAPPED-ADDRESS |
异或映射地址 |
0x0024 |
PRIORITY |
候选者优先级 |
0x0025 | USE-CANDIDATE | 提名该候选者 |
0x8028 | FINGERPRINT | 对消息进行CRC值校验 |
0x8029 | ICE-CONTROLLED | 用于区分ICE角色,answer乙方为controlled角色 |
0x802A | ICE-CONTROLLING | 用于区分ICE角色,offer一方为controlling角色 |
三. connectWebRtcTransport
connectWebRtcTransport 的请求参数为 transportId 和 dtlsParameters。
mediasoup C++ 接收到 TRANSPORT_CONNECT 消息请求后会转到对应的 transport 处理,对于 WebRtcTransport 的处理则需要确定对端选择的 DTLS 角色,并开启 DTLS 交互。
DTLS 交互流程如下所示,关于 DTLS 流程每一步含义说明请参考这篇文章。
执行 DtlsTransport Run 函数后 DTLS 状态进入 CONNECTING,对于 Client 角色,调用 openssl SSL_set_connect_state,SSL_do_handshake,对于 Server 角色调用 openssl SSL_set_accept_state,SSL_do_handshake。
DTLS 协商完成后计算出 SRTP 使用的密钥,通知 WebRtcTransport->OnDtlsTransportConnected,WebRtcTransport 收到后建立 srtpSendSession,最后通知 mediasoup-demo 信令层 dtlsstatechange (connected)。
mediasoup create/connect WebRtcTransport 流程分析相关推荐
- nio的epoll和selector实现流程分析
一.NETTY底层使用的是NIO的selector和epoll进行实现的,select,poll,epoll都是IO多路复用的机制.I/O多路复用就是通过一种机制,一个进程可以监视多个描述符,一旦某个 ...
- android6.0源码分析之Camera API2.0下的初始化流程分析
1.Camera2初始化的应用层流程分析 Camera2的初始化流程与Camera1.0有所区别,本文将就Camera2的内置应用来分析Camera2.0的初始化过程.Camera2.0首先启动的是C ...
- c++builder启动了怎么停止_App 竟然是这样跑起来的 —— Android App/Activity 启动流程分析...
在我的上一篇文章: AJie:按下电源键后竟然发生了这一幕 -- Android 系统启动流程分析zhuanlan.zhihu.com 我们分析了系统在开机以后的一系列行为,其中最后一阶段 AMS( ...
- 车机蓝牙通话流程分析的流程分析
PlantUML Web Server 部分内容参照Android HeadSetClient端通话的传递_天花板之恋的博客-CSDN博客 Android源代码中,如果通话状态有改变,会沿着这样的顺序 ...
- Camera2 openCamera 流程分析
文章目录 一.相机架构 二.应用框架 1.Camera APP 2.AIDL 3.原生框架 4.binder IPC 接口 5.相机服务 6.HAL 三.open流程分析 1. CameraManag ...
- Android-Apk的安装流程分析(二)
Android-Apk的安装流程分析(一) 接着上节的内容来说,之前说到了PackageInstallerSession中调用PackageManaPgerService(简称PMS)的install ...
- 【转载】csr8670--sink工程的大致工作流程分析(以speaker为例)二
csr8670--sink工程的大致工作流程分析(以speaker为例)二 1.编解码任务的初始化 继续接着流程一分析: 1.1 当连接初始化完成之后,如下所示会调用编解码的初始化任务:这个编解码的任 ...
- Android10.0 OTA升级流程分析
原文地址:https://skytoby.github.io/2019/Android%20OTA%E5%8D%87%E7%BA%A7%E6%B5%81%E7%A8%8B%E5%88%86%E6%9E ...
- Android 7.0 挂断电话流程分析
1.图形显示 挂断电话分为本地挂断和远程对方挂断 2.本地挂断 1).点击按钮 先看按键的监听事件 CallCardFragment.java 中有对按钮的监听事件 @Overridepublic v ...
最新文章
- 真我与小我隔着什么?
- 售后服务成OA品牌竞争重要因素
- leetcode 365. Water and Jug Problem | 365. 水壶问题(Java)
- 破拆机器人_灭火体验,消防炮、排烟机器人展示...长安多形式开展消防安全宣传月活动...
- android studio不能更新代码,解决Android Studio 和 Android SDK Manager 无法在线更新的问题....
- [FxCop.设计规则]13. 定义自定义属性参数的访问属性
- 4位无符号比较器设计
- 【洛谷P1795 无穷的序列_NOI导刊2010提高(05)】模拟
- java中number类型能否相除_Java中 如果复数类成员是int型,怎么实现两个复数相除...
- python画有权重网络图_使用Python的networkx绘制精美网络图教程
- java 标识符_java标识符的基础知识
- 【汇编语言】指令寻址
- 主题模型(Topic Model)与LDA算法
- 拓端tecdat|R语言如何找到患者数据中具有差异的指标?(PLS—DA分析)
- CMSIS-RTOS 时间管理之虚拟定时器Virtual Timers
- 联合概率分布与边缘分布
- VS修改MFC工程的程序图标
- 2019年互联网公司月饼颜值大比拼!
- linux创建磁盘的命令,linux中创建磁盘分区的命令是什么
- 运维自动化之ANSIBLE
热门文章
- JavaScript入门记录
- 黑马学习作业练习笔记
- java dataconvert_Spring类型转换 ConversionSerivce Convertor解析
- ANSYS Workbench接触设置面板各参数含义详解
- 51单片机8255扩展c语言,参阅:基于51单片机的实时时钟的设计与开发8255扩展io口1V0.1...
- 固始计算机学校,固始职业教育中心2021年招生简介
- bzoj3514: Codechef MARCH14 GERALD07加强版
- 【转】机器学习发展简史
- 浅谈GPS(全球卫星定位系统)与GPRS的区别与联系
- B树和B+树画图详解