是什么,为什么,如何使用

WebRTC是什么? #

WebRTC是Web实时通信(Real-Time Communication)的缩写,它既是API也是协议。WebRTC协议是两个WebRTC代理协商双向安全实时通信的一组规则。开发人员可以通过WebRTC API使用WebRTC协议。目前WebRTC API仅有JavaScript版本。

可以用HTTP和fetch API来类比。WebRTC协议就是HTTP,而WebRTC API就是fetch API。

除了JavaScript语言,WebRTC协议也可以在其他API/语言中使用。您还可以找到WebRTC的服务器和特定领域的工具。所有这些实现都使用WebRTC协议,因此它们可以彼此交互。

WebRTC协议由IETF工作组在rtcweb中维护。WebRTC API的W3C文档在webrtc-pc

为什么我应该学习WebRTC? #

下面这些就是WebRTC会给您的东西。这份清单并不详尽,只是您在学习旅途中可能会喜欢的一些东西。如果您还不了解其中一些术语,请不要担心,本书将陆续将这些概念教给您。

  • 开放标准
  • 多种实现
  • 在浏览器中可用
  • 强制加密
  • NAT遍历
  • 重新利用现有技术
  • 拥塞控制
  • 亚秒级延迟

WebRTC协议是一组其他技术的集合体 #

这个主题需要整本书来解释。但是,首先,我们将其分为四个步骤。

  • 信令(Signaling)
  • 连接(Connecting)
  • 保护(Securing)
  • 通信(Communicating)

这四个步骤依次发生。上一个步骤必须100%成功,随后的步骤才能开始。

关于WebRTC的一个特殊事实是,每个步骤实际上都是由许多其他协议组成的!为了制作WebRTC,我们将许多现有技术结合在一起。从这个意义上讲,WebRTC更加是自2000年代以来就已经存在的易于理解的技术的组合和配置。

每个步骤都有专门的章节,但是首先从较高的层次上理解它们会有所帮助。由于它们彼此依赖,因此理解这些在进一步解释每个步骤的目的时会有所帮助。

信令:peer如何在WebRTC中找到彼此 #

当WebRTC代理启动时,它不知道与谁通信以及他们将要通信的内容。信令解决了这个问题!信令用于引导呼叫,以便两个WebRTC代理可以开始通信。

信令使用现有协议SDP。SDP是纯文本协议。每个SDP消息均由键/值对组成,并包含“media sections”列表。两个WebRTC代理交换的SDP所包含一些详细信息,如:

  • 代理可访问的IP和端口(候选)
  • 代理希望发送多少路音频和视频流
  • 代理支持哪些音频和视频编解码器
  • 连接时需要使用的值(uFrag/uPwd)
  • 保护时使用的值(证书指纹)

注意,信令通常发生在“out-of-band”。也就是说,应用通常不使用WebRTC本身来交换信令消息。在连接的peer中,任何适合发送消息的架构均可被用于传递SDP信息,许多应用程序都使用其现有的基础结构(例如REST端点,WebSocket连接或身份验证代理)来解决适当客户端之间的SDP传递问题。

使用STUN/TURN进行连接和NAT穿透 #

现在,两个WebRTC代理知道足够的详细信息以尝试相互连接。接下来,WebRTC将使用另一种成熟的技术,称为ICE。

ICE(交互式连接建立)是WebRTC之前的协议。ICE允许在两个代理之间建立连接。这些代理可以在同一网络上,也可以在世界的另一端。ICE是无需中央服务器即可建立直接连接的解决方案。

这里真正的魔法是“ NAT穿透”和STUN/TURN服务器。这两个概念是与另一个子网中的ICE代理进行通信所需的全部。稍后我们将深入探讨这些主题。

ICE成功连接后,WebRTC继续建立加密的传输。此传输用于音频,视频和数据。

使用DTLS和SRTP保护传输层 #

现在我们有了双向通信(通过ICE),我们需要建立安全的通信。这是通过WebRTC之前的两种协议完成的。第一个协议是DTLS(数据报传输层安全性),它只是基于UDP的TLS。TLS是用于保护通过HTTPS进行通信的加密协议。第二种协议是SRTP(安全实时传输协议)。

首先,WebRTC通过在ICE建立的连接上进行DTLS握手来进行连接。与HTTPS不同,WebRTC不使用中央授权来颁发证书。相反,WebRTC只是判断通过DTLS交换的证书是否与通过信令共享的签名相符。然后,此DTLS连接可以被用于传输DataChannel消息。

接下来,WebRTC使用RTP协议进行音频/视频的传输。我们使用SRTP来保护我们的RTP数据包。我们从协商的DTLS会话中提取密钥,用来初始化SRTP会话。在下一章中,我们讨论为什么媒体传输拥有其自己的协议。

我们说完了!您现在可以进行安全的双向通信。如果您的WebRTC代理之间具有稳定的连接,上面这就是您可能需要解决的所有复杂问题。不幸的是,现实世界中存在着数据包丢失和带宽限制,下一章节将介绍我们如何处理它们。

通过RTP和SCTP进行点对点通信 #

现在,我们有了两个具有安全的双向通信功能的WebRTC代理。让我们开始通信!跟前面一样,我们使用两个预先存在的协议:RTP(实时传输协议)和SCTP(流控制传输协议)。SRTP用于加密通过RTP交换的媒体,而SCTP用于发送使用DTLS加密的DataChannel消息。

RTP很小,但是提供了实现实时流式传输所需的功能。重要的是,RTP为开发人员提供了灵活性,因此他们可以根据需要处理延迟,丢失和拥塞。我们将在媒体章节中对此进行进一步讨论。

堆栈中的最终协议是SCTP。SCTP支持许多不同的消息传送选项。您可以选择不可靠的无序交付,以便获得实时系统所需的延迟。

WebRTC是一系列协议的集合 #

WebRTC解决了许多问题。初看起来,这似乎是过度设计的。实际上,WebRTC非常克制。它并未认为它可以更好的解决所有问题。相反,它采纳了许多现有的单一目的技术,并将它们捆绑在一起。

这使得我们可以独立的检查和学习每个部分,而不会毫无头绪。实际上,从另一个角度去看“ WebRTC代理”,它只是许多不同协议的协调器。

graph TB webrtc{WebRTC Agent} sctp{SCTP Agent} dtls{DTLS Agent} ice{ICE Agent} stun{STUN Protocol} turn{TURN Agent} srtp{SRTP Agent} sdp{SDP} rtp{RTP} rtcp{RTCP} webrtc --> ice webrtc --> dtls webrtc --> srtp webrtc --> sdp webrtc --> sctp ice --> turn ice --> stun srtp --> rtcp srtp --> rtp

WebRTC(API)如何工作 #

本部分显示JavaScript API是如何跟协议相对应的。这不只是WebRTC API的一个粗略演示,更像是创建了一个思维模型,以此将所有部分联系在一起。如果您对各部分都不熟悉,那也不要紧。当您了解更多信息时,再回头看看这一部分,可能会很有趣!

new RTCPeerConnection #

RTCPeerConnection是最顶层的"WebRTC会话”。它包含上述所有协议。所有子系统都已就位,但是什么都还没有发生。

addTrack #

addTrack创建一个新的RTP流。并将为这个流生成一个随机的SSRC(Synchronization Source/同步源)。然后,createOffer将生成会话描述符,这个流将被加入其中的媒体部分。每次调用addTrack都会创建一个新的SSRC和对应的媒体部分。

在建立SRTP会话后,这些媒体数据包将被SRTP加密,然后立即通过ICE开始发送。

createDataChannel #

如果没有SCTP关联存在,createDataChannel将创建一个新的SCTP流。默认情况下,SCTP是不启用的,只有在一方请求数据通道时才启动。

在DTLS会话建立之后,SCTP关联将立即通过ICE发送数据包,并使用DTLS加密。

createOffer #

createOffer生成本地状态的会话描述,以与远端Peer共享。

调用createOffer的行为对于本地Peer没有任何改变。

setLocalDescription #

setLocalDescription提交所有请求的更改。 在此调用之前,addTrackcreateDataChannel和类似调用都是临时的。 调用setLocalDescription时,使用由createOffer生成的值。

通常,在此调用之后,您会将offer发送给远端Peer,他们将调用setRemoteDescription,将此offer设入。

setRemoteDescription #

收到远端Peer发来的offer之后,我们通过setRemoteDescription通知本地代理。这就是使用JavaScript API传递“信令”的方式。

双方都调用过setRemoteDescription后,WebRTC代理现在拥有足够的信息来开始进行P2P通信!

addIceCandidate #

addIceCandidate允许WebRTC代理随时添加更多远程ICE候选对象。该API将ICE候选对象发送到ICE子系统,并且对更大的WebRTC连接没有其他影响。

ontrack #

ontrack是从远端Peer收到RTP数据包时触发的回调。传入的RTP数据包应该已在传递给setRemoteDescription的会话描述中声明。

WebRTC使用SSRC并查找关联的MediaStreamMediaStreamTrack,并使用填充的这些详细信息触发此回调。

oniceconnectionstatechange #

oniceconnectionstatechange是ICE代理的状态变化时触发的回调。当网络连接或断开时,您将得到此通知。

onstatechange #

onstatechange是ICE代理和DTLS代理状态的组合。当ICE和DTLS都成功完成时,您将看到此通知。