城东书院 www.cdsy.xyz
这里主要用来记录自己整理的和webRTC相关的一些基本的知识点,后续整理的一些基础和零碎的知识点都会更新在这里。内容大部分来自于webRTC官网、w3c以及一些前辈们的博客中的文章和相关书籍等。
1.peer connection相关的协议
ICE
交互式连接建立Interactive Connectivity Establishment (ICE) 是一个允许你的浏览器和对端浏览器建立连接的协议框架。在实际的网络当中,有很多原因能导致简单的从A端到B端直连不能如愿完成。这需要绕过阻止建立连接的防火墙,给你的设备分配一个唯一可见的地址(通常情况下我们的大部分设备没有一个固定的公网地址),如果路由器不允许主机直连,还得通过一台服务器转发数据。ICE通过使用以下几种技术完成上述工作。
STUN
NAT的会话穿越功能Session Traversal Utilities for NAT (STUN) (缩略语的最后一个字母是NAT的首字母)是一个允许位于NAT后的客户端找出自己的公网地址,判断出路由器阻止直连的限制方法的协议。
客户端通过给公网的STUN服务器发送请求获得自己的公网地址信息,以及是否能够被(穿过路由器)访问。
NAT
网络地址转换协议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
下面是参考https://webrtc.org/native-code/native-apis/的关于两类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连接。
城东书院 www.cdsy.xyz