这里主要用来记录本身整理的和webRTC相关的一些基本的知识点,后续整理的一些基础和零碎的知识点都会更新在这里。内容大部分来自于webRTC官网、w3c以及一些前辈们的博客中的文章和相关书籍等。html
2017年12月3日更新:web
1.peer connection相关的协议
ICE算法
交互式链接创建Interactive Connectivity Establishment (ICE) 是一个容许你的浏览器和对端浏览器创建链接的协议框架。在实际的网络当中,有不少缘由能致使简单的从A端到B端直连不能如愿完成。这须要绕过阻止创建链接的防火墙,给你的设备分配一个惟一可见的地址(一般状况下咱们的大部分设备没有一个固定的公网地址),若是路由器不容许主机直连,还得经过一台服务器转发数据。ICE经过使用如下几种技术完成上述工做。api
STUN浏览器
NAT的会话穿越功能Session Traversal Utilities for NAT (STUN) (缩略语的最后一个字母是NAT的首字母)是一个容许位于NAT后的客户端找出本身的公网地址,判断出路由器阻止直连的限制方法的协议。服务器
客户端经过给公网的STUN服务器发送请求得到本身的公网地址信息,以及是否可以被(穿过路由器)访问。网络

NATsession
网络地址转换协议Network Address Translation (NAT) 用来给你的(私网)设备映射一个公网的IP地址的协议。通常状况下,路由器的WAN口有一个公网IP,全部链接这个路由器LAN口的设备会分配一个私有网段的IP地址(例如192.168.1.3)。私网设备的IP被映射成路由器的公网IP和惟一的端口,经过这种方式不须要为每个私网设备分配不一样的公网IP,可是依然能被外网设备发现。并发
一些路由器严格地限定了部分私网设备的对外链接。这种状况下,即便STUN服务器识别了该私网设备的公网IP和端口的映射,依然没法和这个私网设备创建链接。这种状况下就须要转向TURN协议。框架
TURN
一些路由器使用一种“对称型NAT”的NAT模型。这意味着路由器只接受和对端先前创建的链接(就是下一次请求创建新的链接映射)。
NAT的中继穿越方式Traversal Using Relays around NAT (TURN) 经过TURN服务器中继全部数据的方式来绕过“对称型NAT”。你须要在TURN服务器上建立一个链接,而后告诉全部对端设备发包到服务器上,TURN服务器再把包转发给你。很显然这种方式是开销很大的,因此只有在没得选择的状况下采用。

SDP
会话描述协议Session Description Protocol (SDP) 是一个描述多媒体链接内容的协议,例如分辨率,格式,编码,加密算法等。因此在数据传输时两端都可以理解彼此的数据。本质上,这些描述内容的元数据并非媒体流自己。
参考自:https://developer.mozilla.org/zh-CN/docs/Web/API/WebRTC_API/Protocols
2.Native层peer connection相关API
以目前对peer connection demo的了解,使用native层peer connection API开发的时候主要涉及到下面两类API

同时他也给出使用peer connection 的调用流程
PeerConnectionFactory类提供了用来建立PeerConnection, MediaStream 和 MediaStreamTrack的工厂方法(The PeerConnectionFactory class provides factory methods to create PeerConnection, MediaStream and MediaStreamTrack objects.)
发起通话
- 建立一个PeerConnectionFactoryInterface(Create a PeerConnectionFactoryInterface. Check constructors for more information about input parameters)
- 建立一个PeerConnection对象,提供一个用来生成ICE candidates的指向STUN 以及 TURN服务器的配置结构体。而且提供一个实现了PeerConnectionObserver接口的对象,用来接收PeerConnection的回调。(Create a PeerConnection object. Provide a configuration struct which points to STUN and/or TURN servers used to generate ICE candidates, and provide an object that implements the PeerConnectionObserver interface, which is used to receive callbacks from the PeerConnection)
- 使用PeerConnectionFactory建立本地MediaStreamTracks,经过调用AddTrack方法(或者遗留的AddStream方法)把他们添加到PeerConnection。(Create local MediaStreamTracks using the PeerConnectionFactory and add them to PeerConnection by calling AddTrack (or legacy method, AddStream))
- 建立一个offer,调用SetLocalDescription,把它序列化而且发送到远端peer(Create an offer, call SetLocalDescription with it, serialize it, and send it to the remote peer)
- 一旦一个ICE candidate被生成了PeerConnection会调用observer函数OnIceCandidate,这个candidates必须也被序列化而且发送到远端peer。(Once an ICE candidate has been gathered, the PeerConnection will call the observer function OnIceCandidate. The candidates must also be serialized and sent to the remote peer)
- 一旦接收到了远端peer的应答,调用SetRemoteDescription处理远端的应答(Once an answer is received from the remote peer, call SetRemoteDescription with the remote answer.)
- 一旦从远端peer接收到了远端candidate,调用AddIceCandidate把它提供给PeerConnection(Once a remote candidate is received from the remote peer, provide it to the PeerConnection by calling AddIceCandidate)
接收通话

- 若是PeerConnectionFactoryInterface不存在的话就建立一个(Create PeerConnectionFactoryInterface if it doesn't exist.)
- 建立一个新的PeerConnection(Create a new PeerConnection.)
- 经过调用SetRemoteDescription提供一个远端offer给新的PeerConnection对象(Provide the remote offer to the new PeerConnection object by calling SetRemoteDescription)
- 经过调用CreateAnswer,给远端offer生成一个answer而且把它发送给远端peer(Generate an answer to the remote offer by calling CreateAnswer and send it back to the remote peer)
- 经过调用SetLocalDescription来给新的PeerConnection提供一个本地应答(Provide the local answer to the new PeerConnection by calling SetLocalDescription with the answer)
- 调用AddIceCandidate提供一个远端ICE candidates(Provide the remote ICE candidates by calling AddIceCandidate.)
- 一旦candidate生成了,PeerConnection会调用observer函数OnIceCandidate,把这些candidates发送给远端peer(Once a candidate has been gathered, the PeerConnection will call the observer function OnIceCandidate. Send these candidates to the remote peer)
3. p2p创建流程
在不了解webRTC中p2p的创建流程的状况下去分析peerconnection demo时,感受无从下手,因此应当先了解一下两个peer是怎样创建链接的。
WebRTC用
ICE
协议来保证NAT穿越,因此它有这么一个流程:咱们须要从
STUN Server
中获得一个
ice candidate
,这个东西实际上就是公网地址
- A和B链接上服务端,创建一个TCP长链接(任意协议均可以,WebSocket/MQTT/原生Socket/XMPP),这样一个信令通道就有了。
- A从
ice server
(STUN Server)获取ice candidate
并发送给Socket服务端,并生成包含session description
(SDP)的offer,发送给Socket服务端。
- Socket服务端把A的offer和
ice candidate
转发给B,B会保存下A这些信息。
- 而后B发送包含本身
session description
的answer
(由于它收到的是offer,因此返回的是answer
,可是内容都是SDP)和ice candidate
给Socket服务端。
- Socket服务端把B的
answer
和ice candidate
给A,A保存下B的这些信息。
- 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的音视频流的传输。
至此A与B创建起了一个P2P链接。
参考自: