文章来源:webrtc进阶-信令篇-之三:信令、stun、turn、ice


webRTC支持点对点通讯,但是webRTC仍然需要服务端:
. 协调通讯过程中客户端之间需要交换元数据,
如一个客户端找到另一个客户端以及通知另一个客户端开始通讯。
. 需要处理NAT(网络地址转换)或防火墙,这是公网上通讯首要处理的问题。
所以我们需要了解服务端相关的知识:信令、Stun、trun、ice。

一、什么是信令
信令就是协调通讯的过程,为了建立一个webRTC的通讯过程,客户端需要交换如下信息:
. 会话控制信息,用来开始和结束通话,即开始视频、结束视频这些操作指令。
. 处理错误的消息。
. 元数据,如各自的音视频解码方式、带宽。
. 网络数据,对方的公网IP、端口、内网IP及端口。
信令处理过程需要客户端能够来回传递消息,这个过程在webRTC里面是没有实现的,需要自己创建。
一旦信令服务建立好了,两个客户端之间建立了连接,理论上他们就可以进行点对点通讯了,
这样可以减轻信令服务的压力和消息传递的延迟。
因为信令是我们自己定义的,所以安全性问题跟webrtc无关,需要自己处理。
一旦黑客掌握了你的信令,那他就是控制会话的开始、结束、重定向等等。
最重要的因素在信令安全中还是要靠使用安全协议,如HTTPS,WSS(如TLS),helvetica; line-height:24px">他们能确保未加密的消息不能被截取。为确保信令安全,强烈推荐使用TLS。
二、TURN 和 STUN
元数据是通过信令服务器中转发给另一个客户端,但是对于流媒体数据,一旦会话建立,首先尝试使用点对点连接。
简单一点说就是:
每个客户端都有一个唯一的地址,他能用来和其他客户端进行通讯和数据交换。
现实生活中客户端都位于一个或多个NAT之后,或者一些杀毒软件还阻止了某些端口和协议,helvetica; line-height:24px">或者在公司还有防火墙或代理等等,防火墙和NAT或许是同一个设备,如我们家里用的路由器。
webrtc就是通过 ICE 这套框架来处理复杂的网络环境的,helvetica; line-height:24px">如果想启用这个功能,你必须让你的应用程序传 ICE 服务器的URL:
ICE试着找最好的路径来让客户端建立连接,他会尝试所有可能的选项,然后选择最合适的方案,helvetica; line-height:24px"> ICE首先尝试P2P连接,如果失败就会通过Turn服务器进行转接。
换一个说法就是:
STUN服务器是用来取外网地址的。
TURN服务器是在P2P失败时进行转发的
stun和turn服务的作用主要处理打洞与转发,配合完成ICE协议。
首先尝试使用P2P,
如果失败将求助于TCP,使用turn转发两个端点的音视频数据,turn转发的是两个端点之间的音视频数据不是信令数据。
因为turn服务器是在公网上,所以他能被各个客户端找到,
另外turn服务器转发的是数据流,很占用带宽和资源。
三、ICE技术
基于IP的语音、数据、视频等业务在NGN(Next Generation Network)网络中
所面临的一个实际困难就是如何有效地穿透各种NAT(Network Address Translator)/FW(Fire Wall)的问题。
对此,SIP(会话初始化协议)以往的解决方法由ALGs((Application Layer Gateway Service))、STUN、TURN等方式。
现在有一种新的媒体会话信令穿透NAT/FW的解决方案-交互式连通建立方式ICE。
它通过综合利用现有协议,以一种更有效的方式来组织会话建立过程,
使之在不增加任何延迟同时比STUN等单一协议更具有健壮性、灵活性。
多媒体会话信令协议是在准备建立媒体流传输的代理之间交互信息的协议,
例如SIP、RTSP(real time streaming protocol)等。
媒体流与信令流截然不同,它们所采用的网络通道也不一致。
由于协议自身设计上的原因,使得媒体流无法直接穿透网络地址转换/防火墙(NAT/FW)。
因为它们生存期的目标只是为了建立一个在信息中携带IP地址的分组流,这在遇到NAT/FW 时会带来许多问题。
而且这些协议的目标是通过建立P2P(Peer to Peer)媒体流以减小时延,而协议本身很多方面却与NAT存在兼容性问题,
这也是穿透 NAT/FW的困难所在。
四、ICE简介
交互式连通建立方式ICE(Interactive Connectivity Establishment)并非一种新的协议,
它不需要对STUN、TURN或RSIP进行扩展就可适用于各种NAT。
ICE是通过综合运用上面某几种协议,使之在最适合的情况下工作,以弥补单独使用其中任何一种所带来的固有缺陷。
对于SIP来说,ICE只需要定义一些SDP(Session Description Protocol)附加属性即可,
对于别的多媒体信令协议也需要制定一些相应的机制来实现。
五、多媒体信令
媒体流穿透NAT的过程是独立于某种具体的信令协议的。
通信发生在两个客户端-会话发起者和会话响应者。
初始化信息(Initiate Message)包含了描述会话发起者媒体流的配置与特征,
并经过信令调停者(也叫信令中继),最后到达会话响应者。
假设会话响应者同意通信,接受信息(Accept Message)将产生并反馈至会话初始者,媒体流建立成功。
此外,信令协议还对媒体流参数修改以及会话终止消息等提供支持。
对于SIP,会话发起者即UAC(User Agent Client),会话响应者即UAS(User Agent Server),
初始化消息对应SDP请求里面的INVITE,接受消息对应于SDP应答里面的200 OK,终止消息对应于BYE。
六、流程
1. 收集传输地址
会话发起者需要收集的对象包括:
. 本地传输地址(Local Transport Address)
. 来源传输地址(Derived Transport Address)。
本地传输地址:
通常由主机上一个物理(或虚拟)接口绑定一个端口而获得。
会话发起者还将访问提供UNSAF(Unilateral self-address fixing)的服务器,例如STUN、TURN或TEREDO。
对于每一个本地传输地址,会话者都可以从服务器上获得一组来源传输地址。
显然,实现物理或虚拟连通方式越多,ICE将工作得越好。
但为了建立对等通信,ICE通常要求至少有一个来源地址由位于公网上的中继服务器(如TURN)所提供的,
而且需要知道具体是哪一个来源传输地址。
2. 启动STUN
会话发起者获得一组传输地址后,将在本地传输地址启动STUN服务器,这意味着发送到来源地址的STUN服务将是可达的。
与传统的STUN不同,客户端不需要在任何其它IP或端口上提供STUN服务,也不必支持TLS, ICE用户名和密码已经通过信令协议进行交换。
客户端将在每个本地传输地址上同时接受STUN请求包和媒体包,所以发起者需要消除STUN消息与媒体流协议之间的歧义。
在RTP和RTCP中实现这个并不难,因为RTP与RTCP包总是以0b10(v=2)打头,而STUN是0b00。
对于每个运行STUN服务器的本地传输地址,客户端都必须选择相应的用户名和密码。
用户名要求必须是全局唯一的,用户名和密码将被包含在初始化消息里传至响应者,由响应者对STUN请求进行鉴别。
3. 确定传输地址的优先级
STUN服务器启动后,下一步就是确定传输地址的优先级。
优先级反映了UA在该地址上接收媒体流的优先级别,取值范围在0到1之间,通常优先级按照被传输媒体流量来确定。
流量小者优先,而且对于相同流量者的Ipv6地址比Ipv4地址具有更高优先级。
因此物理接口产生的本地Ipv6传输地址具有最高的优先级,
然后是本地Ipv4传输地址,
然后是STUN、RSIP、TEREDO来源地址,
最后是通过VPN接口获得的本地传输地址。
4. 构建初始化信息(Initiate Message)
初始化消息由一系列媒体流组成,每个媒体流都有一个缺省地址和候选地址列表。
缺省地址通常被Initiate消息映射到SIP信令消息传递地址上,而候选地址列表用于提供一些额外的地址。
对于每个媒体流来说,任意Peer之间实现最大连通可能性的传输地址是由公网上转发服务器(如TURN)提供的地址,
通常这也是优先级最低的传输地址。
客户端将可用的传输地址编成一个候选地址列表(包括一个缺省地址),并且为每个候选元素分配一个会话中唯一的标识符。
该标识符以及上述的优先级都被编码在候选元素的id属性中。一旦初始化信息生成后即可被发送。
5. 响应处理:连通性检查和地址收集
会话应答方接收到初始化信息Initiate Message后,会同时做几个事情:
首先,执行 收集传输地址 中描述的地址收集过程。这些地址可以在呼叫到达前预收集,这样可以避免增加呼叫建立的时间。
当获得来源地址以后,应答方会发送STUN Bind请求,该请求要求必须包含Username属性和Password属性,
属性值为从 “alt”中得到的用户名和密码。
STUN Bind请求还应包括一个Message-Integrity属性,它是由Initiate Message中候选元素的用户名和密码计算得来的。
此外,STUN Bind请求不应有Change-Request或Response-Address属性。
当一个客户端收到Initiate Message时,它将通过其中缺省地址和端口发送媒体流。
如果STUN Bind请求消息引起错误应答,则需要检查错误代码。
如果是401,430,432或500,说明客户端应该重新发送请求。
如果错误代码是400,431和600,那么客户端不必重试,直接按超时处理即可。
6. 生成接受信息(Accept Message)
应答者可以决定是接受或拒绝该通信,若拒绝则ICE过程终止,若接受则发送Accept消息。
Accept消息的构造过程与Initiate Message类似。
7. 接受信息处理
接受过程有两种可能。如果Initiate Message的接受者不支持ICE,
则Accept Message将只包含缺省的地址信息,这样发起方就知道它不用执行连通性检查了。
然而如果本地配置信息要求发起者通过TURN服务器发包来进行连通性检查,
这将意味着那些直接发给响应者的包会被对方防火墙丢弃。
为解决这个问题,发起者需要重新分配一个TURN来源地址,然后使用Send命令。
一旦Send命令被接受,发起者将发送所有的媒体包到TURN服务器,由服务器转发至响应者。
如果Accept Message包含候选项,则发起方处理Accept Message的过程就与响应方处理Initiate Message很相似了。
8. 附加ICE过程
Initiate或Accept消息交换过程结束后,双方可能仍将继续收集传输地址,
这通常是由于某些STUN事务过长而未结束引起,另一种可能是由于Initiate/Accept消息交换时提供了新的地址。
9. ICE到SIP的映射
使用ICE方式穿透NAT,必须映射ICE定义的参数到SIP消息格式中,
同时对其SDP属性进行简单扩展—在SDP的Media块中定义一个新的属性“alt”来支持ICE。
它包含一个候选IP地址和端口,SDP的接受端可以用该地址来替换m和c中的地址。
Media块中可能会有多个alt属性,这时每个alt应该包括不重复的IP地址和端口。
七、写在最后
ICE方式的优势是显而易见的,它消除了现有的UNSAF机制的许多脆弱性。
例如传统的STUN有几个脆弱点:
. 一个是发现过程需要客户端自己去判断所在NAT类型,这实际上不是一个可取的做法。
而应用ICE之后,这个发现过程已经不需要了。
. 另一点脆弱性在于STUN、TURN等机制都完全依赖于一个附加的服务器,
而ICE利用服务器分配单边地址的同时,还允许客户端直接相连,
因此即使STUN或TRUN服务器中有任何一个失败了,ICE方式仍可让呼叫过程继续下去。
. 此外,传统的STUN最大的缺陷在于它不能保证在所有网络拓扑结构中都正常工作,
最典型的问题就是Symmetric NAT。
对于TURN或类似转发方式工作的协议来说,由于服务器的负担过重,很容易出现丢包或者延迟情况。
而ICE方式正好提供了一种负载均衡的解决方案,它将转发服务作为优先级最低的服务,
从而在最大程度上保证了服务的可靠性和灵活性。
. 此外,ICE的优势还在于对Ipv6的支持,目前Cisco等公司正在设计基于ICE方式的NAT/FW解决方案。
由于广泛的适应能力以及对未来网络的支持,ICE作为一种综合的解决方案将有着非常广阔的应用前景。

webrtc进阶-信令篇-之三:信令、stun、turn、ice的更多相关文章

  1. iOS推送通知优先级

    我已设置推送通知并正常工作,但是,有时我会遇到终端设备上的延迟交付.有没有办法我可以将推送的“优先级”键设置为10,以便立即发送推送?

  2. ios – 何时使用Semaphore而不是Dispatch Group?

    我会假设我知道如何使用DispatchGroup,为了解问题,我尝试过:结果–预期–是:为了使用信号量,我实现了:并在viewDidLoad方法中调用它.结果是:从概念上讲,dispachGroup和Semaphore都有同样的目的.老实说,我不熟悉:什么时候使用信号量,尤其是在与dispachGroup合作时–可能–处理问题.我错过了什么部分?

  3. 如何使用Xcode的自动布局调整视图大小

    解决方法在写这个问题时,我意识到了诀窍是什么:在NSPopUpButton的大小检查器中,我不得不降低内容拥抱优先级.显然,这可以控制视图“拥抱”其内容的紧密程度.因此,当拥抱优先级高于调整大小优先级时,视图将不希望增加其大小,因为这意味着其边界与其内容之间具有更多的空白空间.然后在我的特殊情况下,我也可以将两个NSPopUpButtons固定为具有相同的宽度和vo:popUpButtons将完美地调整大小,同时保持间距不变.

  4. ios – 默认的自动布局内容拥抱和内容压缩阻抗优先级值是什么?

    我正在尝试调试自动布局问题,并且知道内容拥抱和内容压缩阻力优先级的默认值将有所帮助.这些是什么?它们是否特定于特定组件?我可以使用常量来引用它们吗?

  5. 在iOS上构建WebRtc

    msg/discuss-webrtc/VJg-fk2-i_0/dtG200DOzsgJ但步骤不明确.某人可以总结这些步骤,以便将来对所有人都有用吗?解决方法我写了一篇详细的博客文章,其中包含有关如何构建WebRTC示例iOS应用程序的所有说明,以及如何在iOS模拟器或实际的iOS设备上运行它.你可以takealookhere阅读细节,这是一个非常漫长的过程.

  6. ios – 为自定义创建的串行异步队列设置优先级

    如何使用GCD为自定义创建的串行异步队列设置高优先级?如果是这样,什么是替代解决方案?解决方法您的队列仍然是串行的.它只会在高优先级全局并发后台队列的一个插槽中一次执行一项任务.一旦创建,串行队列就不能以任何方式“并发”.同样,如果您创建并发队列并将其设置为以串行队列为目标,则它实际上变为串行.这一切都在manpage中有所涉及.

  7. iOS 9中UILabel中的多行文本

    我正在开发iOS项目但是当我更新到iOS9时,我在UILabels中遇到了多线问题.我正在使用Autolayout.有谁知道如何在iOS9中做到这一点?如果是这样,那么问题可能是标签内容压缩阻力优先级太低,尝试将其设置为required或1000.内容压缩阻力告诉视图引擎您的标签可以缩小的优先级.将其设置为必需会强制它不缩小.在InterfaceBuilder中,只需选择标签,点击SizeInspector(小标尺),然后将其更改为1000.或者,在代码中,等价物将是:

  8. ios – 可以在iPhone上使用Web RTC,如果是这样,怎么样?

    可以在iPhone上使用WebRTC,如果是这样,怎么样?我们如何在iPhone中集成WebRTC.解决方法有一些适用于iOS的基于WebRTC的SDK.看看这篇文章:http://bloggeek.me/webrtc-fit-ios/

  9. ios – AutoLayout修改约束

    我发现Autolayout有点困难,所以任何帮助都会非常感激解决方法嗨,你可以做2套约束:>1以优先级高管理您的四视图>1以优先级低管理全屏在点击按钮时调用的方法中,将优先级设置为全屏约束,将优先级设置为四视图约束.

  10. Swift 运算符重载

    但是现在还有另外一个Swift的特性,你应该知道并且会爱上它,它就是运算符重载。例如:我们在SwiftSpriteKitutilitylibrary代码中使用运算符重载去讲多个CGPoints对象相加,例如下面代码:1234letpt1=CGPointletpt2=CGPointletpt3=pt1+pt2letpt4=pt3*100方便吧?当一个人查看你的代码,他们希望操作符的默认行为,这时候运算符重载会使他们迷惑。幸运的是Swift让你能够定义属于你自己的自定义的运算符。

随机推荐

  1. 在airgapped(离线)CentOS 6系统上安装yum软件包

    我有一个CentOS6系统,出于安全考虑,它已经被空气泄漏.它可能从未连接到互联网,如果有,它很长时间没有更新.我想将所有.rpm软件包放在一个驱动器上,这样它们就可以脱机安装而无需查询互联网.但是,我在测试VM上遇到的问题是,即使指定了本地路径,yum仍然会挂起并尝试从在线存储库进行更新.另外,有没有办法使用yum-utils/yumdownloader轻松获取该包的所有依赖项和所有依赖项?目前

  2. centos – 命名在日志旋转后停止记录到rsyslog

    CentOS6.2,绑定9.7.3,rsyslog4.6.2我最近设置了一个服务器,我注意到在日志轮换后,named已停止记录到/var/log/messages.我认为这很奇怪,因为所有日志记录都是通过rsyslog进行的,并且named不会直接写入日志文件.这更奇怪,因为我在更新区域文件后命名了HUPed,但它仍然没有记录.在我停止并重新启动命名后,记录恢复.这里发生了什么?

  3. centos – 显示错误的磁盘大小

    对于其中一个磁盘,Df-h在我的服务器上显示错误的空白区域:Cpanel表明它只有34GB免费,但还有更多.几分钟前,我删除了超过80GB的日志文件.所以,我确信它完全错了.fdisk-l/dev/sda2也显示错误:如果没有格式化,我该怎么做才能解决这个问题?并且打开文件描述符就是它需要使用才能做到这一点.所以…使用“lsof”并查找已删除的文件.重新启动写入日志文件的服务,你很可能会看到空间可用.

  4. 如何在centos 6.9上安装docker-ce 17?

    我目前正在尝试在centOS6.9服务器上安装docker-ce17,但是,当运行yuminstalldocker-ce时,我收到以下错误:如果我用跳过的标志运行它我仍然得到相同的消息,有没有人知道这方面的方法?

  5. centos – 闲置工作站的异常负载平均值

    我有一个新的工作站,具有不寻常的高负载平均值.机器规格是:>至强cpu>256GB的RAM>4x512GBSSD连接到LSI2108RAID控制器我从livecd安装了CentOS6.564位,配置了分区,网络,用户/组,并安装了一些软件,如开发工具和MATLAB.在启动几分钟后,工作站负载平均值的值介于0.5到0.9之间.但它没有做任何事情.因此我无法理解为什么负载平均值如此之高.你能帮我诊断一下这个问题吗?

  6. centos – Cryptsetup luks – 检查内核是否支持aes-xts-plain64密码

    我在CentOS5上使用cryptsetupluks加密加密了一堆硬盘.一切都很好,直到我将系统升级到CentOS6.现在我再也无法安装磁盘了.使用我的关键短语装载:我收到此错误:在/var/log/messages中:有关如何装载的任何想法?找到解决方案问题是驱动器使用大约512个字符长的交互式关键短语加密.出于某种原因,CentOS6中的新内核模块在由旧版本创建时无法正确读取512个字符的加密密钥.似乎只会影响内核或cryptsetup的不同版本,因为在同一系统上创建和打开时,512字符的密钥将起作用

  7. centos – 大量ssh登录尝试

    22个我今天登录CentOS盒找到以下内容这是过去3天内的11次登录尝试.WTF?请注意,这是我从我的提供商处获得的全新IP,该盒子是全新的.我还没有发布任何关于此框的内容.为什么我会进行如此大量的登录尝试?是某种IP/端口扫描?基本上有4名匪徒,其中2名来自中国,1名来自香港,1名来自Verizon.这只发生在SSH上.HTTP上没有问题.我应该将罪魁祸首子网路由吗?你们有什么建议?

  8. centos – kswap使用100%的CPU,即使有100GB的RAM也可用

    >Linux内核是否应该足够智能,只需从内存中清除旧缓存页而不是启动kswap?

  9. centos – Azure将VM从A2 / 3调整为DS2 v2

    我正在尝试调整前一段时间创建的几个AzureVM,从基本的A3和标准A3到标准的DS2v2.我似乎没有能力调整到这个大小的VM.必须从头开始重建服务器会有点痛苦.如果它有所不同我在VM中运行CentOS,每个都有一个带有应用程序和操作系统的磁盘.任何人都可以告诉我是否可以在不删除磁盘的情况下删除VM,创建新VM然后将磁盘附加到新VM?

  10. centos – 广泛使用RAM时服务器计算速度减慢

    我在非常具体的情况下遇到服务器速度下降的问题.事实是:>1)我使用计算应用WRF>2)我使用双XeonE5-2620v3和128GBRAM(NUMA架构–可能与问题有关!

返回
顶部