WebRTC技术文档 -- 5.ICE(笔记)

WebRTC建立网络连接的过程称为ICE(Interactive Connectivity Establishment,互动式连接建立),具体过程为:收集Candidate、交换Candidate、按优先级尝试连接。

Candidate指可连接的候选者。每个候选者是包含address(IP地址)、port(端口号)、protocol(传输协议)、CandidateType(Candidate类型)、ufrag(用户名)等内容的信息集。WebRTC将Candidate分为host、srflx、prflx和relay四类,优先级依次由高到低。

5.1 ICE过程

5.1.1 收集Candidate

1)host类型的Candidate根据主机的网卡个数来决定,一般一个网卡对应一个IP地址,给每个IP地址随机分配一个端口从而生成一个host类型的Candidate。

2)srflx类型的Candidate通过STUN服务器获得的IP地址和端口号生成。

3)relay类型的Candidate通过TURN服务器获得的IP地址和端口号生成。

5.1.2 交换Candidate

WebRTC收集好Candidate后通过信令系统将它们发送给对端,对端接收后会与本地的Candidate形成CandidatePair(连接候选者对,即一个本地Candidate,一个远端Candidate)。Candidate的交换不是等所有Candidate收集好后才进行,而是边收集边交换。

5.1.3 尝试连接

WebRTC形成CandidatePair后开始尝试连接,一旦连接成功不再进行尝试,但发现新的Candidate仍然继续交换。

WebRTC的ICE机制会选择最好的链路传输音视频数据,即如果通信双方在同一网段,则优先使用内网链路;如果通信双方不在同一网段,则优先使用P2P;如果上述方式都无法连通,则使用relay服务进行中转。

ICE的连通率几乎可以达到100%。在内网和P2P无法连通的情况下,还可以通过中继方式连通,从而大大提高了WebRTC的连通率。

WebRTC中的ICE既考虑了数据传输的效率,又考虑了网络的连通率,实现起来还很简单。

5.2 NAT

NAT(Network Address Translation,网络地址交换)主要解决IPv4地址不够用和安全问题。通过多台主机共用一个公网IP地址来减缓IPv4地址不够用的问题。使用NAT后,主机隐藏在内网,这样黑客很难访问到内网主机,从而达到保护内网主机的目的。

NAT其实就是一种地址映射技术,它在内网地址与外网地址之间建立了映射关系。

在RFC3489协议中,将NAT分为完全锥型、IP限制锥型、端口限制锥型和对称型四种。

5.2.1 完全锥型NAT

NAT打洞成功后,所有知道该洞的主机都可以通过它与内网主机进行通信。这里的"洞"指的是在NAT上建立了一个内外网的映射表,包括内网IP、内网端口、映射的外网IP以及映射的外网端口。

5.2.2 IP限制锥型NAT

NAT打洞成功后,只有与之打洞成功的外网主机才能通过该洞与内网主机通信,其他外网主机即使知道洞也不能与之通信。

当外网主机通过IP限制锥型NAT向内网主机发送消息时,NAT会检测数据包头中的源IP地址是否在NAT映射表中有记录,只有登记过的外网IP地址才可以通过NAT。

IP限制锥型NAT的打洞映射表包括内网IP、内网端口、映射的外网IP、映射的外网端口以及被访问主机的IP列表。

5.2.3 端口限制锥型NAT

除了像IP限制锥型NAT一样对IP地址进行检测外,还要对端口进行检测。

端口限制锥型NAT的打洞映射表包括内网IP、内网端口、映射的外网IP、映射的外网端口以及被访问主机的IP和端口的组合列表。

5.2.4 对称型NAT

内网主机每次访问不同的外网主机时,都会生成一个新洞。对称型NAT映射表中映射的外网IP地址和外网端口会随着访问目的主机不同而变化。

对称型NAT的打洞映射表包括内网IP、内网端口、映射的外网IP、映射的外网端口、被访问主机的IP和被访问主机的端口。

5.2.5 NAT类型检测

图中虚线左半部分用来判断内网主机是否有NAT防护,右半部分用来探测主机在哪种NAT类型之后。

内网主机进行NAT类型检测时,需要用到两台STUN服务器,每台STUN服务器需要两块网卡,每块网卡需要配置公网IP地址。

5.2.6 NAT穿越

1)各NAT之间可穿越表

2)IP限制型NAT与对称型NAT如何互通

① X主机与S服务器通信,交换外网IP、端口等信息,X主机创建NAT映射表。

② A主机与S服务器通信,交换外网IP、端口等信息,A主机创建NAT映射表。

③ X主机向A主机发送数据,X主机在NAT映射表中增加A主机的IP地址,数据未穿越被A主机的NAT丢弃。

④ A主机向X主机发送数据,A主机在NAT映射表中创建与X主机相关的映射表,数据可以穿越NAT到达X主机。

5.3 网络中继

当NAT之间无法打通时,WebRTC使用TURN协议通过中转的方式实现端与端之间的通信。

5.3.1 TURN协议中转数据

TURN协议采用了客户端/服务器模式,其服务器称为TurnServer,客户端称为TurnClient。

① 主机X(TurnClient)向TurnServer的3478端口发送Allocate指令,TurnServer收到该消息后,在TURN服务端分配一个与TurnClient相对应的relay地址,任何发向relay地址的数据都会被转发到TurnClient端。

② 主机A和主机B称为Peer端,可以使用UDP向TurnServer的relay地址发送数据,TurnServer根据映射关系将relay地址收到的数据转给对应的TurnClient,实现TurnClient与Peer之间的互通。

5.3.2 WebRTC如何使用TURN协议

主机A和主机B都是TurnClient,可以通过TURN协议与TurnServer建立联系;它们也是彼此的Peer端,可以向对端的relay地址发送数据,从而让TurnServer将数据中转给对端。

5.3.3 STUN错误码

### 如何解决 Maven 项目中 `org.webrtc:google-webrtc:1.0.32006` 依赖缺失问题 当遇到 `org.webrtc:google-webrtc:1.0.32006` 依赖无法找到的情况时,可以采取以下措施来解决问题。 #### 配置仓库地址 确保项目的构建配置文件正确指定了所需的仓库位置。对于 Gradle 构建工具,在根目录下的 `build.gradle.kts` 文件内添加特定的 Maven 仓库: ```kotlin dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { maven { url = uri("https://raw.githubusercontent.com/alexgreench/google-webrtc/master") } google() mavenCentral() } } ``` 上述设置会优先尝试从指定的 GitHub 地址下载 WebRTC 库,并且还会检查 Google 的官方存储库以及中央 Maven 存储库[^1]。 #### 更新版本号 确认使用的版本号是最新的稳定版。如果当前使用的是较旧或不存在的版本,则可能会导致依赖解析失败。根据最新信息显示,应该使用如下声明方式引入该依赖项: ```groovy implementation 'org.webrtc:google-webrtc:1.0.32006' ``` 此命令适用于 Groovy DSL 编写的 build 脚本;如果是 Kotlin DSL 则应写作 `implementation("org.webrtc:google-webrtc:1.0.32006")`[^4]。 #### 清理缓存并重新同步 有时本地缓存中的数据可能已损坏或是过期,这也会引起依赖加载错误。执行清理操作可以帮助排除此类情况带来的干扰。可以通过 IDE 提供的功能或者命令行运行相应的指令来进行清理工作。例如,在 Android Studio 中可以选择菜单栏里的 “File -> Invalidate Caches / Restart”,也可以通过终端输入 gradlew clean 命令完成同样的目的。 另外需要注意的是,某些情况下即使远程服务器上有资源可用,但如果之前有过查找失败的经历,那么这些记录会被保存到本地磁盘上作为缓存的一部分而阻止后续成功的请求被处理。因此建议删除 `.gradle/caches/modules-2/files-2.1/org.webrtc/google-webrtc/*` 下的相关条目后再重试一次同步过程[^5]。 #### 添加额外的镜像源 考虑到网络连接不稳定等因素可能导致访问默认仓库的速度慢甚至不可达的问题,可以在 settings.xml 或者 buildscript 中增加阿里云或其他国内常用的 Maven 镜像站点链接以提高获取速度和成功率: ```xml <mirrors> <mirror> <id>aliyun</id> <name>Aliyun Maven</name> <url>https://maven.aliyun.com/repository/public</url> <mirrorOf>*</mirrorOf> </mirror> </mirrors> ``` 以上 XML 片段适合于 Apache Maven 用户;而对于采用 Gradle 的开发者来说则需调整为对应的语法结构[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱学习的程序媛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值