WebRTC 入门,你需要知道的知识

324 阅读7分钟

WebRTC 基础

WebRTC (Web Real-Time Communications) 是一项实时通讯技术,它允许网络应用或者站点,在不借助中间媒介的情况下,建立浏览器之间点对点(Peer-to-Peer)的连接,实现视频流和(或)音频流或者其他任意数据的传输。允许网页直接连接

整体示意图

WebRTC整体架构

WebRTC 的实现流程

  • ClientA首先创建PeerConnection对象,然后打开本地音视频设备,将音视频数据封装成MediaStream添加到PeerConnection中。
  • ClientA调用PeerConnection的CreateOffer方法创建一个用于offer的SDP对象,SDP对象中保存当前音视频的相关参数。ClientA通过PeerConnection的SetLocalDescription方法将该SDP对象保存起来,并通过Signal服务器发送给ClientB。
  • ClientB接收到ClientA发送过的offer SDP对象,通过PeerConnection的SetRemoteDescription方法将其保存起来,并调用PeerConnection的CreateAnswer方法创建一个应答的SDP对象,通过PeerConnection的SetLocalDescription的方法保存该应答SDP对象并将它通过Signal服务器发送给ClientA。
  • ClientA接收到ClientB发送过来的应答SDP对象,将其通过PeerConnection的SetRemoteDescription方法保存起来。
  • 在SDP信息的offer/answer流程中,ClientA和ClientB已经根据SDP信息创建好相应的音频Channel和视频Channel并开启Candidate数据的收集,Candidate数据可以简单地理解成Client端的IP地址信息(本地IP地址、公网IP地址、Relay服务端分配的地址)。
  • 当ClientA收集到Candidate信息后,PeerConnection会通过OnIceCandidate接口给ClientA发送通知,ClientA将收到的Candidate信息通过Signal服务器发送给ClientB,ClientB通过PeerConnection的AddIceCandidate方法保存起来。同样的操作ClientB对ClientA再来一次。
  • 这样ClientA和ClientB就已经建立了音视频传输的P2P通道,ClientB接收到ClientA传送过来的音视频流,会通过PeerConnection的OnAddStream回调接口返回一个标识ClientA端音视频流的MediaStream对象,在ClientB端渲染出来即可。同样操作也适应ClientB到ClientA的音视频流的传输。

信令服务器(Signaling server)

1.用来控制通信开启或者关闭的连接控制消息

2.发生错误时用来彼此告知的消息

3.媒体流元数据,比如像解码器、解码器的配置、带宽、媒体类型等等

4.用来建立安全连接的关键数据

5.外界所看到的的网络上的数据,比如P地址、端口等

6.信令服务器并不需要理解和解释信令数据内容。虽然它基于 SDP但这并不重要:通过信令服务器的消息的内容实际上是一个黑盒。

how

使用Nodejs下的socket.io库来实现WebRTC信令服务器

ICE服务器

可以分为帮助两个客户端打洞建立 P2P 连接的 STUN 服务器,还有如果连不通就直接转发的 TURN 服务器。ICE 的信息叫 Candidate,可以通过 SDP 交换,或者通过 Trickle。

WebRTC连接方式

  • 通过本地直接连接(开启多个浏览器页面对话)
  • 通过公共ip地址(STUN服务器,获取外网地址,通过NAT墙)
  • 通过WebRTC TURN服务器路由连接媒体(传递音视频数据)

WebRTC 多方通信

  • Mesh(Multiple Direct Connections)
  • MCU(Multipoint Conferencing Unit)
  • SFU(Selective Forwarding Unit)

Mesh

网状结构

只能支持4-6人左右

没有中心节点,实现很简单

MCU

由一个服务器和多个终端组成一个星形结构

浏览器压力小,服务器压力较大

SFU

由一个服务器和多个终端组成一个星形结构(不对音视频进行混流)

NAT(Network Address Translation)

NAT又称网络掩蔽、IP掩蔽在计算机网络中是一种在IP数据包通过路由器防火墙时重写来源IP地址或目的IP地址的技术

  • 优先STUN (Session Traversal Utilities for NAT),NAT会话穿越应用程序
  • 备选TURN (Traversal Using Relay NAT) ,中继NAT实现的穿透

SDP

SDP(Session Description Protocol) 是一种会话描述协议,基于文本,其本身并不属于传输协议,需要依赖其它的传输协议(比如 SIP 和 HTTP)来交换必要的媒体信息,用于两个会话实体之间的媒体协商。

//SDP协议的具体格式如下,分为两部分:会话描述和媒体描述。其中带星号(*)的表示可选。
Session description
    v=  (protocol version)
    o=  (originator and session identifier)
    s=  (session name)
    i=* (session information)
    u=* (URI of description)
    e=* (email address)
    p=* (phone number)
    c=* (connection information -- not required if included in all media)
    b=* (zero or more bandwidth information lines)
    [...One or more time descriptions ("t=" and "r=" lines)]
    z=* (time zone adjustments)
    k=* (encryption key)
    a=* (zero or more session attribute lines)
    [...Zero or more media descriptions]

Time description
    t=  (time the session is active)
    r=* (zero or more repeat times)

Media description, if present
    m=  (media name and transport address)
    i=* (media title)
    c=* (connection information -- optional if included at session level)
    b=* (zero or more bandwidth information lines)
    k=* (encryption key)
    a=* (zero or more media attribute lines)
//caller生成本地描述信息
const offer = await peerConnection.createOffer();

//caller设置本地描述信息
await peerConnection.setLocalDescription(offer);

//caller发送本地描述信息至远端
const signalServer = new WebSocket('ws://[xxx.signal.com](http://xxx.signal.com/)');
signalServer.send({
  type: 'offer',
  data: offer,
});


//callee设置远端描述信息
await peerConnection.setRemoteDescription(offer);

//callee生成本地应答描述信息
const answer =await peerConnection.createAnswer();

//callee设置本地描述信息
await peerConnection.setLocalDescription(answer);

ICE

交互式连接建立。它是一种端到端交互的技术,可以让两个终端相互知道对方的公网IP,可以不借助一个公网server完成端到端(Peer to peer,P2P)的通信。

当各端调用 setLocalDescription 后,WebRTC就开始建立网络连接,主要包括收集candidate、交换candidate和按优先级尝试连接,该过程被称为ICE(Interactive Connectivity Establishment,交互式连接建立)。其中每个 candidate 都包含IP地址、端口、传输协议、类型等信息。

iceConnectionState

         "new": 建立ICE连接
                   ICE 代理正在搜集地址或者等待远程候选可用。
    "checking": 收集候选
                ICE 代理已收到至少一个远程候选,并进行校验,无论此时是否有可用连接。
                同时可能还在继续收集候选。
   "connected": 匹配到可用候选
                已为连接的所有组件找到可用的本地和远程候选配对,并且已建立连接。
                此时仍然会继续测试远程候选以便发现更优的连接。同时可能在继续收集候选。
   "completed": 匹配完成,连接建立
                ICE代理已经发现了可用的连接,不再测试远程候选。
      "failed":没有合适候选
                ICE候选测试了所有远程候选没有发现匹配的候选。
                也可能有些候选中发现了一些可用连接。
"disconnected":网络波动或者串流断开
                RTPeerConnection至少有一个组件连接失败。
      "closed": 断开ICE
                ICE代理关闭,不再应答任何请求。

STUN

Session Traversal Utilities for NAT,是一种技术可以让位于NAT后的设备可以查找自己的公网IP

PeerConnectionClient

PeerConnectionClient类,他的作用是与信令服务器(server)来进行TCP通信。它可以通过在两台机器间生成 Session Description 的数据交换协议来实现。呼叫方发送一个 offer(请求),被呼叫方发出一个 answer(应答)来回答请求。双方 - 呼叫方以及被呼叫方,最开始的时候都要建立他们各自的 RTCPeerConnection 对象。

MediaStream

MediaStream API 是连接 WebRTC API 和底层物理流的中间层,webRTC将音视频经过Vocie / Video engine进行处理后,再通过MediaStream API给暴露给上层使用。MediaStream 接口是一个媒体内容的流.。一个流包含几个轨道,比如视频和音频轨道。

通过 navigator.getUserMedia() 获取MediaStream

RTCDataChannel

RTCDataChannel 接口是WebRTC API的一个功能,可以让您在两个对等体之间打开一个通道,您可以通过该通道发送和接收任意数据。

 // 创建 let Channel = RTCPeerConnection.createDataChannel('messagechannel', options);
// messagechannel 可以看成是给 DataChannel 取的别名,限制是不得超过65,535 字节。  // options 可以设置一些属性,一般默认就好。 
// 接收 RTCPeerConnection.ondatachannel = function(event) {let channel = event.channel;
}

RTCPeerConnection sample

  • getUserMedia 获取音频和视频流
  • RTCPeerConnection
pc = new RTCPeerConnection(null);
pc.onaddstream = gotRemoteStream;
pc.addStream(localStream);
pc.createOffer(gotOffer);function gotOffer(desc) {
  pc.setLocalDescription(desc);
  sendOffer(desc);
}function gotAnswer(desc) {
  pc.setRemoteDescription(desc);
}function gotRemoteStream(e) {
  attachMediaStream(remoteVideo, e.stream);
}

通过offer和answer交换SDP描述符

  • createOffer()

  • setLocalDescription()

  • setRemoteDescription()

  • createAnswer()

  • setLocalDescription()

相关知识点

参考链接