IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> WebRTC candidate -> 正文阅读

[网络协议]WebRTC candidate

一. 前言

? ? ? ? WebRTC 音视频通信的双方需要知道对端的通信地址才能进行通信,WebRTC 采用 ICE 方式与通信对端建立通信连接,ICE 中很关键的一个步骤就是收集候选者信息,本端需要将自己的主机候选者,NAT 映射后的候选者以及中继候选者等信息发送给对端,对端也需要发送候选者信息给到本端,双方进行媒体连通性检测,检测成功后才能进行通信。

二. candidate

? ? ? ? 候选者也叫?candidate,它是一个网络地址信息,例如通信时本地准备使用的 IP 是 192.168.1.2,端口是 10001,采用 UDP 协议,那么这些信息组合起来就是一个 host?candidate,一个 candidate 包含协议,IP,端口和类型。

例如:a=candidate:...UDP...192.168.1.2 10001 typ host

? ? ? ? 除了 host 类型的 candidate 外还有 srflx candidate 以及 relay candidate 等,各种候选者的含义说明如下。

????????主机候选者(Local Address)是本地使用的 IP 地址和端口,例如通过 ipconfig 查看到 WLAN 网卡的 IP 地址是 192.168.1.2,并且准备使用 10001 端口。

? ? ? ? 服务端映射候选者(Server Reflexive Address)是 NAT 映射后使用的 IP 地址和端口。

? ? ? ? 中继候选者(Relayed Address) 是 TURN 服务器开辟的 IP 地址和端口,TURN 服务器是用来应对当通信对端?NAT 穿越失败无法建立 P2P 通信时,通过 TURN 服务器转发数据包,TURN 服务器一般都部署在带公网 IP 的机器上。

? ? ? ? WebRTC example 提供了一个可以收集 candidate 的工具,通过该工具我们可以收集 Local Address 和 Server Reflexive Address,如果你搭建了 TURN 服务器,将 TURN 服务地址添加到 ICE Servers 中,你还可以收集到 Relayed Address。

三. 源码剖析

????????当本地通过 createOffer 生成 local SDP 后会再调用?setLocalDescription 设置到本地描述信息中,setLocalDescription 中就会进行 candidate 收集。

? ? ? ? 如下当 PeerConnection::DoSetLocalDescription 完成 ApplyLocalDescription 后会执行 transport_controller_->MaybeStartGathering() 开始 candidate 收集。

void PeerConnection::DoSetLocalDescription(
    std::unique_ptr<SessionDescriptionInterface> desc,
    rtc::scoped_refptr<SetSessionDescriptionObserver> observer) {
  // 省略...(详见src/pc/peer_connection.cc)
  error = ApplyLocalDescription(std::move(desc));

  // 省略...

  // MaybeStartGathering needs to be called after posting
  // MSG_SET_SESSIONDESCRIPTION_SUCCESS, so that we don't signal any candidates
  // before signaling that SetLocalDescription completed.
  transport_controller_->MaybeStartGathering();

  // 省略...
}

????????如果当前线程不是网络线程,则向网络线程发送 MaybeStartGathering 的任务,否则执行 dtls->ice_transport()->MaybeStartGathering() 的逻辑。

????????MaybeStartGathering 逻辑如下,如果当前状态为未收集过 candidate 的状态或者准备重启 ICE 的状态,则进入正在收集的状态,并且往?allocator_sessions_ 添加一个 session(该 session 是一个 PortAllocatorSession 对象),然后调用?session 的?StartGettingPorts。

?

????????调用?StartGettingPorts 后的驱动流程为:GetPortConfiguarations -> OnConfigReady -> OnAllocate -> OnAllocationSequenceObjectsCreated。

?

?

????????GetPortConfiguarations 首先创建 PortConfiguration 对象 config,然后往 config 对象添加 stun_servers,turn_servers 地址信息。

?

? ? ? ? OnConfigReady 则是将?PortConfiguration 对象塞入 configs_ 中。

?

?

????????OnAllocate 中调用了 DoAllocate,DoAllocate 中最重要的逻辑就是为每个 Network 生成一个 AllocationSequence 对象(如果你对 Network 对象不太熟悉,可以先阅读这篇博客了解 WebRTC 收集网卡信息的流程)。

?

????????DoAllocate 中使用 Network,?PortConfiguration 以及 sequence_flags 创建 AllocationSequence 对象后,会再为 AllocationSequence 对象执行 Init 初始化。?

????????AllocationSequence::Init 调用 BasicPacketSocketFactory::CreateUdpSocket 创建出 socket,该 socket 绑定了 Network 对应的 ip 地址以及从 [min_port, max_port] 范围挑选的一个可用端口,socket 创建的调用流程如下。

?

?

?????????AllocationSequence::Init 执行完成后会再调用 AllocationSequence::Start,该函数主要是给网络线程发送 MSG_ALLOCATION_PHASE 消息,驱动 UDPPort,TcpPort,StunPort,RelayPort 等对象的创建。

?

????????我们以 CreateUDPPorts 为例说明 host?candidate 是如何收集的,对于 CreateStunPorts,CreateRelayPorts 将在后续博客讲解。

????????CreateUDPPorts 逻辑如下,首先是创建出 UDPPort 对象,然后通过 BasicPortAllocatorSession::AddAllocatedPort 添加 UDPPort 进行处理。

????????BasicPortAllocatorSession::AddAllocatedPort 主要是为 port content_name, component 等属性,并关联一些事件的回调处理函数,然后执行 PrepareAddress。

????????PrepareAddress 调用了 OnLocalAddressReady,OnLocalAddressReady 又调用 AddAddress 创建 candidate。

?

? ? ? ? 至此本地候选者即创建完毕,其他候选者的创建流程后续博客将会说明,候选者信息创建完成后会给网络线程发送 MSG_SEQUENCEOBJECTS_CREATED 消息,回调 OnAllocationSequenceObjectsCreated 候选者创建完成。

?

四. 参考资料

RFC5245

RFC8445

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-04-09 18:53:50  更:2022-04-09 18:54:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/31 4:43:47-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码