企业网站建设 广州,上虞区建设局网站,pageadmin的应用,安徽网站建设详细策划本文是《Web性能权威指南》第四部分——WebRTC的读书笔记。 第一部分——网络技术概览#xff0c;请参考网络技术概览#xff1b; 第二部分——无线网络性能#xff0c;请参考无线网络性能#xff1b; 第三部分——HTTP#xff0c;请参考HTTP#xff1b; 第四部分——浏览…本文是《Web性能权威指南》第四部分——WebRTC的读书笔记。 第一部分——网络技术概览请参考网络技术概览 第二部分——无线网络性能请参考无线网络性能 第三部分——HTTP请参考HTTP 第四部分——浏览器API与协议的前四章请参考浏览器API与协议。
WebRTC
Web Real-Time CommunicationWeb实时通信WebRTC由一组标准、协议和JS API组成用于实现浏览器之间端到端的音频、视频及数据共享。WebRTC使得实时通信变成一种标准功能任何Web应用都无需借助第三方插件和专有软件而是通过简单的JavaScript API即可利用。
要实现涵盖音频和视频的电话会议等完善、高品质的RTC应用、端到端的数据交换需要浏览器具备很多新功能音频和视频处理能力、支持新应用API、支持好几种新网络协议。浏览器把前述这些复杂性抽象成三个主要API
MediaStream获取音频和视频流RTCPeerConnection音频和视频数据通信RTCDataChannel任意应用数据通信。
WebRTC通过UDP传输数据。
标准和WebRTC的发展
WebRTC架构由十余个标准组成涵盖应用和浏览器API以及很多必要的协议和数据格式
W3C的Web Real-Time CommunicationsWEBRTCWorking Group负责制定浏览器APIIETF的Real-Time Communication in Web-browsersRTCWEB工作组负责定义协议、数据格式、安全及其他在浏览器中实现端到端通信必需的内容。
设计WebRTC时也会考虑已有通信系统VOIPVoiceOver IP、各种SIP客户端、PSTNPublic Switched Telephone Network公共交换电话网等。
音频和视频引擎
要实现电话会议功能浏览器必须访问系统硬件采集音频和视频还需对它们分别加以处理以增强品质保证同步而且要适应不断变化的带宽和客户端之间的网络延迟调整输出的比特率。
接收端的处理过程相反必须实时解码音频和视频流并适应网络抖动和时延。 如上图浏览器会负责
音频流降噪和回声消除处理、优化的窄带或宽带音频编解码器编码、错误补偿算法消除网络抖动和丢包造成的损失视频的影像品质选择最优的压缩和编解码方案应用抖动和丢包补偿。
浏览器要动态调整其处理流程以适应不断变化的音频和视频流及网络条件。
W3C的Media Capture and Streams规范规定一套JS API 解读
MediaStream对象包含一或多个TrackMediaStreamTrackMediaStream中的多个Track相互之间是同步的输入源可以是物理设备如麦克风、摄像头、用户硬盘或另一端远程服务器中的文件MediaStream的输出可被发送到一或多个目的地本地的视频或音频元素、后期处理的JS代理或远程另一端。
MediaStream对象表示一个实时的媒体流以便应用代码从中取得数据操作个别的Track和控制输出。所有的音频和视频处理比如降噪、均衡、影像增强等都由音频和视频引擎自动完成。
getUserMedia()从底层平台取得音频和视频流的简单API负责获准访问用户的麦克风和摄像机并获取符合指定要求的流。取得流之后还可以将它们提供给其他浏览器API
通过Web Audio API在浏览器中处理音频通过Canvas API采集个别视频帧并加以处理通过CSS3和WebGL API为输出的流应用各种2D/3D特效。
当前的WebRTC实现使用Opus和VP8编解码器
Opus编解码器用于音频支持固定和可变的比特率编码适合的带宽范围为6~510Kbit/s。这个编解码器可以无缝切换以适应不同的带宽。VP8编解码器用于视频编码要求带宽为100~2000Kbit/s比特率取决于流的品质如180p360p720p。
实时网络传输
实时通信讲究的就是及时、当下。因此处理音频和视频流的应用一定要补偿间歇性的丢包音频和视频编解码器可以填充小的数据空白通常对输出品质的影响也很小。类似地应用必须实现自己的逻辑以便因传输其他应用数据而丢包或延迟时快速恢复。及时和低延迟比可靠更重要。
UDP协议才更适合用于传输实时数据。UDP提供下列不服务
不保证消息交付不确认不重传无超时不保证交付顺序不设置包序号不重排不会发生队首阻塞不跟踪连接状态不必建立连接或重启状态机不需要拥塞控制不内置客户端或网络反馈机制。
UDP是浏览器实时通信的基础但要完全达到WebRTC的要求浏览器还需要位于其上的大量协议和服务的支持如下图所示 WebRTC的协议分层
ICEInteractive Connectivity EstablishmentRFC 5245STUNSession Traversal Utilities for NATRFC 5389TURNTraversal Using Relays around NATRFC 5766SDPSession Description Protocol会话描述协议RFC 4566DTLSDatagram Transport Layer SecurityRFC 6347SCTPStream Control Transport ProtocolRFC 4960SRTPSecure Real-Time Transport ProtocolRFC 3711
ICE、STUN和TURN是通过UDP建立并维护端到端连接所必需的。DTLS用于保障传输数据的安全加密是WebRTC强制的功能。SCTP和SRTP属于应用层协议用于在UDP之上提供不同流的多路复用、拥塞和流量控制以及部分可靠的交付和其他服务。
RTCPeerConnection API RTCPeerConnection接口负责维护每一个端到端连接的完整生命周期
管理穿越NAT的完整ICE工作流发送自动STUN持久化信号跟踪本地流跟踪远程流按需触发自动流协商提供必要的API以生成连接提议接收应答允许查询连接的当前状态等。
RTCPeerConnection把所有连接设置、管理和状态都封装在一个接口中。
DataChannel API用于实现端到端之间的任意应用数据交换类似于WebSocket但却是端到端交换。而且底层传输机制的属性也是可定制的。每个DataChannel可以经过配置提供以下特性
发送消息可靠或部分可靠的交付发送消息有序或乱序交付。
不可靠的乱序交付等同于原始UDP即消息可能到达也可能不到达而且到达次序也没有保证。然而可让信道部分可靠也就是设定重传的最大次数或时间限制WebRTC的各个层负责处理确认和超时。
建立端到端的连接
打开XHR、EventSource或新WebSocket会话很简单依赖于定义完善的HTTP握手机制协商连接参数都假定客户端可访问到目标服务器比如服务器具有公开的可路由到的IP地址或客户端和服务器都在一个内部网中。
WebRTC两端则很可能分别位于自己的私有网络中中间还隔着一或多层NAT。为了发起会话首先必须找到两端的候选IP和端口穿越NAT检查连接以期找到可用路径。
要想成功地建立端到端的连接必须首先解决另外几个问题
必须通知另一端想打开一个端到端的连接以便它知道开始监听到来的分组必须找出两端之间建立连接所需的路由线路并在两端传播这个信息必须交换有关媒介和数据流的必要信息如协议、编码等。
WebRTC解决其中一个问题内置ICE协议会执行必要的路由和连接检查。然而发送通知信号和协商会话仍然要由应用负责。
发信号和协商会话
在检查连接或协商会话前必须知道能否将信息发送到另一个端另一端是否愿意建立连接。为此必须发出一个信号而另一端必须返回应答。问题来了如果另一端没有监听数据包怎么办最低限度需要一个共享的发信通道。 WebRTC把发送信号和协议的选择交给应用而标准有意未给发送信号的过程提供建议或实现。这样可让现有通信基础设施中的其他发信协议能够互操作包括如下几个协议
SIPSession Initiation Protocol会话初始协议应用级发信协议广泛用于通过IP实现的语音通话VoIP和视频会议JingleXMPP协议的发信扩展用于VoIP和视频会议的会话控制ISUPISDN User PartISDN用户部分全球各大公共电话交换网中用于启动电话呼叫的发信协议。
WebRTC应用可以选择已有的任何发信协议和网关利用既有通信系统协商一次通话或视频会议。 发信服务器可以作为已有通信网络的网关此时由网络负责将连接提议发送给目标端然后再将应答返回给WebRTC客户端以初始化信息交换。而应用也可使用自定义发信信道可能由一或多台服务器和一个自定义通信协议构成如果两端都连到同一个发信服务那这个服务就可以为它们传递消息。
可与WebRTC互操作的通信网关如开源的Asterisk。Asterisk有一个WebSocket模块该模块支持将SIP作为发信协议浏览器建立到Asterisk网关的WebSocket连接然后两者通过交换SIP消息来协商会话。
SDP
Session Description Protocol会话描述协议。
应用实现共享的发信通道后接下来就可以发起WebRTC连接
// 初始化共享的发信通道
var signalingChannel new SignalingChannel();
var pc new RTCPeerConnection({});
// 向浏览器请求音频流
navigator.getUserMedia({ audio: true }, gotStream, logError);
function gotStream(stream) {// 通过RTCPeerConnection注册本地音频流pc.addstream(stream);// 创建端到端连接的SDP提议描述pc.createOffer(function(offer) {// 以生成的SDP作为端到端连接的本地描述pc.setLocalDescription(offer);// 通过发信通道向远端发送SDP提议signalingChannel.send(offer.sdp);});
}
function logError() { ... }WebRTC使用SDP描述端到端连接的参数。SDP不包含媒体本身的任何信息仅用于描述会话状况表现为一系列的连接属性要交换的媒体类型音频、视频及应用数据、网络传输协议、使用的编解码器及其设置、带宽及其他元数据。
SDP是一个基于文本的简单协议RFC 4568用于描述会话属性。WebRTC应用不必直接处理SDP。JSEP JavaScript Session Establishment Protocol JS会话建立协议定义对RTCPeerConnection对象几个方法的简单调用就把SDP所有的内部工作全都隐藏起来。生成提议之后就可通过发信通道将它发送给远端。如何编码SDP取决于应用SDP字符串可以像前面那样作为简单的文本blob直接传输也可以将它编码成任意格式后再传输。Jingle协议提供从SDP到XMPPXML格式的映射。
要建立端到端的连接两端都必须遵循一个对称的工作流以交换各自音频、视频及其他数据流的SDP描述。
ICE
端与端之间往往有很多层防火墙和NAT设备阻隔。
查询操作系统获知IP地址如果有多块网卡就需要多个IP地址将IP地址加端口号追加到生成的SDP字符串中。
WebRTC框架可处理大部分复杂工作
每个RTCPeerConnection连接对象都包含一个ICE代理ICE代理负责收集IP地址和端口ICE代理负责执行两端的连接检查ICE代理负责发送连接持久化信息。
设置好会话描述后无论本地还是远程本地ICE代理会自动开始发现本地端所有可能的候选IP和端口的进程
ICE代理向操作系统查询本地IP地址如果有配置ICE代理会查询外部STUN服务器以取得本地端的公共IP和端口号如果有配置ICE代理会将TURN服务器追加为最后一个候选项假如端到端的连接失败数据将通过指定的中间设备转发。
每发现一个新候选项一个IP加一个端口号代理就会自动通过RTCPeerConnection对象注册它并通过一个回调函数onicecandidate通知应用。ICE在完成收集工作后也会再触发同一个回调函数以通知应用。
var ice {iceServers: [// STUN服务器配置为使用谷歌的公共测试服务器{url: stun:stun.l.google.com:19302},// TURN服务器用于端到端连接失败时转发数据{url: turn:userturnserver.com, credential: pass}]};
var signalingChannel new SignalingChannel();
var pc new RTCPeerConnection(ice);
navigator.getUserMedia({ audio: true }, gotStream, logError);
function gotStream(stream) {pc.addstream(stream);pc.createOffer(function(offer) {// 应用本地会话描述初始化ICE收集过程pc.setLocalDescription(offer);});
}pc.onicecandidate function(evt) {// 预订ICE事件监听ICE收集完成if (evt.target.iceGatheringState complete) {local.createOffer(function(offer) {console.log(Offer with ICE candidates: offer.sdp);// 生成SDP提议此时包含发现的ICE候选项signalingChannel.send(offer.sdp);});}
}
// 包含ICE候选项的提议
// acandidate:1862263974 1 udp 2113937151 192.168.1.73 60834 typ host // 本地端的私有ICE候选项
// acandidate:2565840242 1 udp 1845501695 50.76.44.100 60834 typ srflx // STUN服务器返回的公有ICE候选项ICE代理处理大部分复杂工作ICE收集过程是自动触发的STUN查找是在后台执行的而发现的候选项也会自动通过RTCPeerConnection对象注册。上述过程完成后可生成SDP提议并通过发信通道发送给另一端。另一端接收到ICE候选项后就可建立端到端的连接只要RTCPeerConnection对象设置远程会话描述包含另一端的一组候选IP和端口号ICE代理就会执行连接检查以确定能否抵达另一端。
ICE代理发送消息STUN绑定请求另一端接收之后必须以一个成功的STUN响应确认。如果这个过程完成则代表有一条端到端连接的路由线路相反如果所有候选项都绑定失败要么将RTCPeerConnection标记为失败要么回退到靠TURN转发服务器建立连接。
ICE代理自动确定连接检查时候选项的次序和优先级首先检查本地IP地址然后是公共IP最后才检查TURN。建立连接后ICE代理周期性地向另一端发送STUN请求以此保证连接的持久化。
Trickle ICE
ICE收集过程决不是瞬间就能完成的取得本地IP地址很快但查询STUN服务器需要经过到外部服务器的往返还有另一次端到端的STUN连接检查。Trickle ICE是对ICE协议的扩展用于在于实现端与端之间的增量收集和连接检查
两端交换没有ICE候选项的SPD提议发现ICE候选项之后通过发信通道发送到另一端新候选描述一就绪立即执行ICE连接检查。
不等到ICE收集过程完成而是依靠发信通道向另一端递增地交付更新从而加快协商。
Trickle ICE导致发信通道的流量增加但可显著减少初始化端到端连接的时间。所有WebRTC应用都应该考虑这一点尽快发送提议然后依次发现依次发送ICE候选项。
跟踪ICE收集和连接状态
内置的ICE框架负责候选项发现、连接检查、持久化等。开发者要做的只是在初始化RTCPeerConnection对象时指定STUN和TURN服务器。
iceGatheringState属性保存本地端候选项的收集状态
new对象刚刚创建还没有连网gatheringICE代理正在收集本地候选项completeICE代理收集过程完成。 如上图iceConnectionState属性中保存着端到端的连接状态
newICE代理正在收集候选项且/或正在等待远程候选项的到来checkingICE代理至少已经收到来自一个组件的远程候选项而且正在检查候选项但尚未发现连接除检查外可能仍然在收集connectedICE代理已经找到一条通过所有组件的可用连接但仍在检查其他候选项以确定是否存在更好的连接此时仍有可能还在收集completedICE代理已经完成收集和检查且发现通过所有组件的连接failedICE代理检查完所有候选项但至少有一个组件的连接失败其他一些组件的连接可能成功disconnected一或多个组件的活动检查失败相对failed更严重在不稳定的网络上可能会间歇性触发不需要采取什么行动closedICE代理已经关闭不再响应STUN请求。
ICE代理最重要的目标就是识别端到端之间的可行路径。可ICE代理不会就此止步。即便是连接已经建立ICE代理也可能周期性地尝试其他候选项以确定其他路径的性能是否更好。
Chrome提供一个工具可检查任何WebRTC连接的工作流和状态。打开标签页chrome://webrtc-internals可检查所有打开的端到端连接查看交换的SDP描述
完整示例
初始化WebRTC连接
响应WebRTC连接
simpleWebRTC库使用一个用于穿透NAT的公共STUN服务器初始化了RTCPeerConnection使用getUserMedia请求音频和视频流并初始化了连接到它自己发信服务器的WebSocket连接。
交付媒体和应用数据
要实现实时通信还需要流量控制、拥塞控制、错误校验、带宽预测、延迟机制、通信加密等能力。
WebRTC又在UDP之上增加几层协议
DTLSDatagram Transport Layer Security数据报传输层安全用于加密传输应用数据时针对要传输的媒体数据协商密钥SRTPSecure Real-Time Transport安全实时传输用于传输音频和视频流SCTPStream Control Transport Protocol流控制传输协议用于传输应用数据。
通过DTLS实现安全通信
DTLS本质上就是TLS为兼容UDP的数据报传输而做一些微小修改。
DTLS解决下列问题
TLS要求可靠的有序的适合分段的握手记录以协商信道如果在混合多个分组的基础上对记录分段就不能保证TLS的完整性校验如果记录的顺序不对也不能保证TLS的完整性校验。
DTLS对TLS记录协议的扩展就是为每条握手记录明确添加分段偏移字段和序号。这样就满足有序交付的条件也能让大记录可以被分段成多个分组并在另一端再进行组装。DTLS握手记录严格按照TLS协议规定的顺序传输顺序不对就报错。DTLS还要处理丢包问题两端都使用计时器如果预定时间内没有收到应答就重传握手记录。
记录序号、偏移值和重传计时器让DTLS在UDP之上实现握手。为保证过程完整两端都要生成自已签名的证书然后按照常规的TLS握手协议走。 完整的DTLS握手需要两次往返。即建立端到端的连接会产生额外延迟。
WebRTC客户端自动为每一端生成自已签名的证书。因此也就没有证书链需要验证。DTLS保证加密和完整性但把身份验证工作留给应用。最后在满足握手要求的基础上DTLS为处理常规记录可能出现的分段和乱序问题又增加两条重要的规则
DTLS记录必须刚好放到一个网络分组中必须有一个分组密码用于加密记录数据。
常规TLS记录最大可以达到16KB。TCP可以处理分段和组装但UDP不提供这些服务。结果为适应UDP协议的乱序发送也为了最大程度保持其语义每个携带应用数据的DTLS记录都必须放到一个UDP分组中。类似地由于它们潜在依赖记录数据的有序发送因此也不允许使用流密码。
通过SRTP和SRTCP交付媒体
WebRTC以完全托管的形式提供媒体获取和交付服务从摄像头到网络再从网络到屏幕。WebRTC应用指定获取流的媒体约束然后通过RTCPeerConnection对象注册它们。从此以后就都是浏览器提供的WebRTC媒体和网络引擎的事编码优化、处理丢包、网络抖动、错误恢复、流量、控制等。
RTPReal-Time Transport Protocol实时传输协议由RFC 3550定义。
WebRTC实际上并不是通过IP网络实时交付音频和视频的第一个应用。WebRTC只是重用了VoIP电话使用的传输协议、通信网关和各种商业或开源的通信服务
安全实时传输协议SRTPSecure RTP通过IP网络交付音频和视频等实时数据的标准安全格式。安全实时控制传输协议SRTCPSecure Real-time Control Transport Protocol通过SRTP流交付发送和接收方统计及控制信息的安全控制协议。
SRTP为通过IP网络交付音频和视频定义标准的分组格式。SRTP本身并不对传输数据的及时性、可靠性或数据恢复提供任何保证机制它只负责把数字化的音频采样和视频帧用一些元数据封装起来以辅助接收方处理这些流。 解读
每个SRTP分组都包含一个自动递增的序号以便接收端检测和发现媒体数据是否乱序每个SRTP分组都包含一个时间戳表示媒体净荷第一字节的采样时间用于多个媒体流如音频和视频的同步每个SRTP分组都包含一个SSRC标识符这是个别媒体流中每个分组的唯一流ID每个SRTP分组可以包含其他可选的元数据每个SRTP分组都包含加密的媒体净荷以及可选的认证标签后者用于验证分组的完整性。
SRTP分组中包含媒体引擎实时回放流必需的所有信息。而控制每个SRTP分组交付则是SRTCP协议的责任SRTCP针对每个媒体流实现独立的外部反馈渠道。
SRTCP会跟踪发送及丢失字节和分组的数量跟踪每个SRTP分组的序号、交错到达抖动以及其他SRTP统计信息。然后两端定时交换这些数据以便调整每个流的发送速率、编码品质和其他参数。
SRTP和SRTCP直接在UDP之上运行共同完成对应用提供的音频和视频流的实时适配和优化。WebRTC应用不会接触内部的SRTP或SRTCP协议如果你要构建自定义的WebRTC客户端那得直接操作这两个协议否则浏览器会替你搭建好所有必要的基础设施。
关于SRTP和SRTCP还需要考虑另外一些细节
SRTP和SRTCP都会加密应用净荷数据WebRTC要求但它们都没有提供协商密钥的机制这就是为什么必须先进行DTLS握手的原因DTLS握手会为两端确定一个共享密钥随后的SRTP和SRTCP可以使用这个密钥。SRTP和SRTCP都要求对不同的流分配不同的端口而这对于NAT或防火墙后面的客户端当然就是一个问题。为解决这个问题WebRTC使用另一个多路复用扩展以便向同一个目标端口交付多个流以及相应的控制信道。IETF还制定一个新的拥塞控制算法该算法利用SRTCP的反馈对WebRTC应用生成的音频和视频流进行优化。
通过SCTP交付应用数据
WebRTC对RTCDataChannel接口及其传输协议有哪些要求
传输层必须支持多个独立信道的复用每个信道必须支持有序或乱序交付每个信道必须支持可靠或不可靠交付每个信道可以支持应用定义的优先级。传输层必须提供一个面向消息的API每条应用消息都可能在传输层被分段和组装。传输层必须实现流量和拥塞控制机制。传输层必须保证数据的机密性和完整性。
TCP、UDP与SCTP比较
对比项目TCPUDPSCTP可靠性可靠不可靠可配置交付次序有序乱序可配置传输方式面向字节面向消息面向消息流量控制支持不支持支持拥塞控制支持不支持支持
DataChannel
设置与协商
配置消息次序和可靠性
部分可靠交付与消息大小
使用场景及性能
音频、视频和数据流
多方通信架构
基础设施及容量规划
数据效率及压缩
性能检查表
注意事项
发信服务 使用低延迟传输机制提供足够的容量建立连接后考虑使用DataChannel发信。 防火墙和NAT穿越 初始化RTCPeerConnection时提供STUN服务器尽可能使用增量ICE虽然发信次数多但建立连接速度快提供STUN服务器以备端到端连接失败后转发数据预计并保证TURN转发时容量足够用。 数据分发 对于大型多方通信考虑使用超级节点或专用的中间设备中间设备在转发数据前考虑先对其进行优化或压缩。 数据效率 对音频和视频流指定适当的媒体约束优化通过DataChannel发送的二进制净荷考虑压缩通过DataChannel发送的UTF-8数据监控DataChannel缓冲数据的量同时注意适应网络条件变化。 交付及可靠性 使用乱序交付避免队首阻塞如果使用有序交付把消息大小控制到最小以降低队首阻塞的影响发送小消息1150字节以便将分段应用消息造成的丢包损失降至最低对部分可靠交付设置适当的重传次数和超时间隔正确地设置取决于消息大小、应用数据类型和端与端之间的延迟。