WebRTC 之ICE浅谈
前言
ICE全称Interactive Connectivity Establishment:交互式连通建立方式。
ICE参照RFC5245建议实现,是一组基于offer/answer模式解决NAT穿越的协议集合。
它综合利用现有的STUN,TURN等协议,以更有效的方式来建立会话。
客户端侧无需关心所处网络的位置以及NAT类型,并且能够动态的发现最优的传输路径。
Classic STUN(RFC3489)的劣势:
Classic STUN 有着诸多局限性,例如:
- 不能确定获得的公网映射地址能否用于P2P通信
- 没有加密方法
- 不支持TCP穿越
- 不支持对称型NAT的穿越
- 不支持IPV6
STUN(RFC5389)协议
RFC5389是RFC3489的升级版
- 支持UDP/TCP/TLS协议
- 支持安全认证
ICE利用STUN(RFC5389)
Binding Request和Response,来获取公网映射地址和进行连通性检查。同时扩展了STUN的相关属性:
- PRIORITY:在计算candidate pair优先级中使用
- USE-CANDIDATE:ICE提名时使用
- tie-breaker:在角色冲突时使用
TURN协议
ICE使用TURN(RFC
5766)协议作为STUN的辅助,在点对点穿越失败的情况下,借助于TURN服务的转发功能,来实现互通。端口与STUN保持一致
TURN消息都遵循 STUN 的消息格式,除了ChannelData消息。
- 支持UDP/TCP/TLS协议,适用于UDP被限制的网络。
- 支持IPV6。
TURN的流程:
l 创建Allocation:
client 使用allocation
transaction创建relay 端口,并在allocation的响应中回复给client。
当allocation创建后需要使用refresh
request来保活,默认lifetime为10分钟。
l 创建Permission:
由allocation创建Permission,每个Permission
由 IP 地址 和lifetime组成。
有两种方法来创建和刷新Permission
- CreatePermission
- ChannelBind
l 收发数据:
- CreatePermission使用Send and Data indication消息
- ChannelBind使用ChannelData消息
ICE介绍
- 1. ICE 的角色
分为 controlling和controlled。
Offer 一方为controlling角色,answer一方为controlled角色。
- 2. ICE的模式
分为FULL ICE和Lite
ICE:
FULL ICE:是双方都要进行连通性检查,完成的走一遍流程。
Lite ICE: 在FULL
ICE和Lite ICE互通时,只需要FULL ICE一方进行连通性检查, Lite一方只需回应response消息。这种模式对于部署在公网的设备比较常用。
- 3. Candidate
媒体传输的候选地址,组成candidate
pair做连通性检查,确定传输路径,有如下属性:
Type 类型有:
Host/Srvflx/Relay/Prflx
Componet
ID
传输媒体的类型,1代表RTP;2代表 RTCP。
WebRTC采用Rtcp-mux方式,也就是RTP和RTCP在同一通道内传输,减少ICE的协商和通道的保活。
Priority
Candidate的优先级。
如果考虑延时,带宽资源,丢包的因素,Type优先级高低一般建议如下顺序:
host
> srvflx > prflx > relay
Base
是指candidate 的基础地址。
Srvflx address 的base 是本地host address。
host address和 relayed
address 的base 是自身。
- 4. Candidate pair
由本端和远端candidate组成的pair,有自己的优先级。
pair优先级的计算是取决candidate的priority。
priority
= 2^32*MIN(G,D) + 2*MAX(G,D) + (G>D?1:0)
G:controlling candidate 优先级
D:controlled candidate 优先级
ICE选择高优先级的candidate
pair。
- 5. Checklist
由candidate
pair生成按优先级排序的链表,用于ICE连通性检查。
- 6. Validlist
由连通性检查成功的candidate
pair按优先级排序的链表,用于ICE提名和选择最终路径。
ICE过程
- 1. Gather candidates
根据Componet ID:
获取本机host address.
从STUN服务器获取
srvflx address.
从TURN服务器获取 relay
address.
同时生成foundation。
- 2. 删除重复的candidate
收集地址完成后,需要去掉重复的candidate,如果两个candidate的地址一样,并且Base地址也一样,则删除它。
- 3. 交换candidates
ICE 使用offer/answer方式,双方通过SDP协商交换candidate信息.
Candidate信息包括type,foundation,base,component
id,transport
SDP a行格式如下:
“a=candidate:1
1 UDP 9654321 212.223.223.223 12345
typ srflx raddr 10.216.33.9 rport 54321”
表示 foundation为1,媒体是RTP,采用UDP协议,公网映射地址为212.223.223.223:12345,优先级为9654321,type为srflx,base地址为10.216.33.9:54321
- 4. 生成candidate pairs
在本端收到远端candidates后,将Component
ID和transport protocol相同的candidates组成pair。
修整candidate
pair,如果是srvflx地址,则需要用其base地址替换。
对端也是同样的流程。
- 5. 生成checklist
将candidate
pairs按照优先级排序,生成checklist,供连通性检查使用。
- 6. 连通性检查
Ordinary
checks 两端都按照各自checklist分别进行检查。
Triggered checks 收到对端的检查时,也在对应的candidate
pair上发起连通性检查,以提高效率
如果checklist里有relay
candidate,则必须首先为relay candidate创建permission。
- 7. 发送连通性检查请求
ICE 使用STUN
binding request/response,包含Fingerprint检验校验机制。
如果A收到B的response,则代表连通性检查成功,否则需要进行重传直到超 时。
在建立连接时,如果没有响应,则会以RTO时间进行重传,每次翻倍,直到最大重传次数。
STUN请求 采用STUN short-term
credential方式认证,
STUN USERNAME属性 ”RemoteUsername:localUsername”
两端在SDP协商时交换ice-pwd和ice-ufrag,以得对端用户名和密码。
STUN 检查请求中需要检查地址的对称性,请求的源地址是响应的目的地址,请求的目的地址是响应的源地址,否则都设置状态为
Failed。
- 8. 生成validlist
将连通性检查成功的candidate pair并按优先级排序加入validlist,这时本地candidate填写的是公网映射地址,remote
candidate填写的是对端发送的STUN binding request地址。
- 9. 提名candidate pair
由controlling来提名哪对candidate
pair为valid pair
提名方式又分为普通提名和进取型提名
普通提名方式会做两次连通性检查,在第一次做连通性检查时不会带上USE-CANDIDATE属性,而是在生成的validlist里选择pair再进行一次连通性检查,这时会带上USE-CANDIDATE属性,并且置位nominated
flag。
进取型方式则是每次发送连通性检查时都会带上USE-CANDIDATE属性,并且置位nominated flag,不会再去做第二次连通性检查。
10. 选择最终传输地址
ICE在提名的valid
pair里选择优先级最高那对作为本次ICE流程传输地址。
ICE状态
- Waiting:还未开始连通性检查,从checklist中选择合适优先级的pair进行检查
- In-Progress:连通性检查已经开始,但还未结束
- Succeeded:该pair 连通性检查已经完成并且成功
- Failed:失败
- Frozen:连通性检查还未开始

ICE保活
- 对于每个ICE通道,都需要为其会话进行保活。
- 采用STUN binding request或者STUN
binding indication。 - 如果没有收到响应,则会重传,直到最大重传次数。
ICE角色冲突解决
- 当两端角色都为controlling或者controlled角色冲突时,在连通性检查阶段,要求发送binding
request消息里必须要带上tie-breaker属性。 - 当出现冲突时,比较tie-breaker大小,值比较大的则被认为是controlling,同时回应487错误给对端,对端收到487错误后切换角色。
结束语
随着WebRTC的应用越来越普遍,无论是Native端还是Web端,由于广泛的适应 能力以及对未来网络的支持,ICE作为一种综合的解决方案将有着非常广阔的应用前景。

网易云信翻译了W3C推荐标准WebRTC 1.0:
Real-time CommunicationBetween Browsers,并提供《WebRTC1.0: 浏览器间实时通讯》中文版免费下载。
- 对于WebRTC初学者,本文档可以作为学习教程,帮助你快速对WebRTC有全面且详细的了解,学习相关API的使用,其附带的示例代码也是很好的学习资料;
- 对于WebRTC资深开发者,本文档可以作为开发中的使用手册,根据所提供的函数调用链或是算法流程进行开发或bug定位;
- 对于高阶玩家,也可通过阅读本文档对WebRTC工作组反馈改进意见。
限时免费下载,WebRTC开发者必备。
想要阅读更多技术干货、行业洞察,欢迎关注网易云信博客。
了解网易云信,来自网易核心架构的通信与视频云服务。
网易云信(NeteaseYunXin)是集网易18年IM以及音视频技术打造的PaaS服务产品,来自网易核心技术架构的通信与视频云服务,稳定易用且功能全面,致力于提供全球领先的技术能力和场景化解决方案。开发者通过集成客户端SDK和云端OPEN API,即可快速实现包含IM、音视频通话、直播、点播、互动白板、短信等功能。
WebRTC 之ICE浅谈的更多相关文章
- 浅谈Windows API编程
WinSDK是编程中的传统难点,个人写的WinAPI程序也不少了,其实之所以难就难在每个调用的API都包含着Windows这个操作系统的潜规则或者是windows内部的运行机制…… WinSDK是编程 ...
- 浅谈 Fragment 生命周期
版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Fragment 文中如有纰漏,欢迎大家留言指出. Fragment 是在 Android 3.0 中 ...
- 浅谈 LayoutInflater
浅谈 LayoutInflater 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/View 文中如有纰漏,欢迎大家留言指出. 在 Android 的 ...
- 浅谈Java的throw与throws
转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...
- 浅谈SQL注入风险 - 一个Login拿下Server
前两天,带着学生们学习了简单的ASP.NET MVC,通过ADO.NET方式连接数据库,实现增删改查. 可能有一部分学生提前预习过,在我写登录SQL的时候,他们鄙视我说:“老师你这SQL有注入,随便都 ...
- 浅谈WebService的版本兼容性设计
在现在大型的项目或者软件开发中,一般都会有很多种终端, PC端比如Winform.WebForm,移动端,比如各种Native客户端(iOS, Android, WP),Html5等,我们要满足以上所 ...
- 浅谈angular2+ionic2
浅谈angular2+ionic2 前言: 不要用angular的语法去写angular2,有人说二者就像Java和JavaScript的区别. 1. 项目所用:angular2+ionic2 ...
- iOS开发之浅谈MVVM的架构设计与团队协作
今天写这篇博客是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇博客的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...
- Linux特殊符号浅谈
Linux特殊字符浅谈 我们经常跟键盘上面那些特殊符号比如(?.!.~...)打交道,其实在Linux有其独特的含义,大致可以分为三类:Linux特殊符号.通配符.正则表达式. Linux特殊符号又可 ...
随机推荐
- MySQL 8 InnoDB 集群生产部署
生产部署InnoDB集群 1.先决条件 InnoDB集群使用组复制技术,所以InnoDB中的实例需要满足组复制要求.可以查看MySQL文档中组复制相关的部分,也可以通过AdminAPI提供的dba.c ...
- 《趣谈 Linux 操作系统》学习笔记(一):为什么要学 Linux 及学习路径
前言:学习的课程来自极客时间的专栏<趣谈 Linux 操作系统>,作者用形象化的比喻和丰富的图片让课程变得比较易懂,为了避免知识看过就忘,打算通过写学习笔记的形式记录自己的学习过程. Li ...
- .net mvc 自定义错误页面
1.Global.asax.cs中,加入如下代码 protected void Application_Error(Object sender, EventArgs e) { Exception ex ...
- TC SRM556 OldBridges
题意 有一个包含\(n\)个点的图,点的编号分别为\(0\)到\(n-1\).有若干双向边连接两个点,有些边可以经过无限次,有些边最多只能经过(双向)两次.Alice计划从\(a1\)到\(a2\)进 ...
- 洛谷题解 P1134 【阶乘问题】
原题传送门 题目描述 也许你早就知道阶乘的含义,N阶乘是由1到N相乘而产生,如: 12!=1×2×3×4×5×6×7×8×9×10×11×12=479,001,600 12的阶乘最右边的非零位为6. ...
- MY_0002:导出单位设置
1,导出模型给canvas工具用时,设置单位为m,再参考模型所占网格大小.
- 对象浅拷贝Object.assign
const target = { a: { b: { c: { d: 1 } }, e: 5, f: 6, h: 10 } } const source = { a: { b: { c: { d: 1 ...
- Android列表类视图之基本适配器BaseAdapter
说到列表视图,不难联想到前面提到过的数组适配器,但是数组适配器只能搭建文本选择项,扩展能力并不强,Android提供了一种适应性更强的基本适配器BaseAdapter,该适配器允许开发者在别的代码中进 ...
- CSS:overflow 内容溢出属性
overflow 属性规定当内容溢出元素框时发生的事情 值 描述 visible 默认值.内容不会被修剪,会呈现在元素框之外. hidden 内容会被修剪,并且其余内容是不可见的. scroll 内容 ...
- CF1093E Intersection of Permutations [分块 +bitset]
大家好, 我非常喜欢暴力数据结构, 于是就用分块A了此题 分块题,考虑前缀和 \(b_i\) 表示 bitset 即 \(0\) ~ $i $ 出现过的数字,然后考虑直接暴力复制块然后前缀和,修改也很 ...