**STURN & TRUN &ICE
在上述的Mesh架构下,需要进行透传以便通信双方能够正常进行,这就使用到的STURN和TURN以及ICE技术。**
WebRTC的信令传输可以慢些但需要可靠,而流媒体则实时性优,可以存在丢包、错包;这就意味着需要两套网络传输协议,一套是基于TCP的可靠传输协议用于信令等传输,一套是基于UDP的TRP协议用于实时多媒体数据的传输。其协议栈如下图所示:
ICE(Interactive Connectivity Establishment)协议(RFC 5245)
STUN(Session Traversal Utilities for NAT)(RFC5389)
TURN(Traversal Using Relays around NAT)(RFC 5766)
这三个协议是基于UDP协议建立和维持P2P连接的必要网络组件;DTLS(Datagram Transport Protocol)用于P2P双方数据安全传输。
WebRTC代码架构
WebRTC目录结构如下所示,其中紫色的为目录。
各个目录的功能如下:
api目录:是对WebRTC功能件的封装,以更方便应用层调用,这里封装的内容包括audio、video、数据通道以及RTP传输,并在create_peerconnection_factory.h文件中定义了P2P通信的核心类PeerConnectionFactoryInterface;
audio目录:这里的audio层是用于发送和接收音频数据流的网络层,真实硬件的采集播放放在adm(audio device module),增强处理放在apm(audio processing module)里,adm和apm并不在这一目录下;
base目录:提供了一些依赖OS的基础函数,比如内存管理等;
build相关目录:使用与编译WebRTC的,在编译小节中会有编译说明;
call目录:从字面可以知道是用于通信用的,主要是RTP和RTCP相关协议的封装一遍WebRTC使用;
common_audio和common_video目录:音视频的各种算法都可能用到的,比如fir滤波,环形缓冲区,窗函数等;
examples:P2P等各个平台各种例子所在的目录;
media:是对video和audio增强和编解码的封装层,即video engine和audio engine。
modules:音视频具体功能实现所在的目录,如音视频编解码实现;音频混音、处理以及设备管理,视频采集播放以及数据发送和占用带宽估计等;
pc(peer connection)目录:P2P连接实现的核心目录;
sdk目录:android平台应用层Java和MAC平台应用层Object C访问natvie层的桥接层;
server端
STUN服务器:用于获取设备的外网地址;
TURN服务器:在P2P通信失败后用于中继;
ICE框架,整合了TURN和STUN。
信令服务器:负责端到端的连接,如SDP,candidate等;
因为由于IPv4地址数量不够用和安全的问题,开会的双方基本都在防火墙和NAT之后,通过运营商接入公网,当在家时手机、电脑、网络电视通过电信路由器上网时,路由器分配给我们的地址就是“192.168.XXX.XXX”,但是在公网上我们的数据头地址被转换成电信服务商提供的地址了,如果双发希望直接通信而不需要公共服务器中转(加大了延迟和丢包的不确定性)数据包,这时需要NAT穿透技术,STUN和TURN就是这种透传协议,ICE是一套整合了这两个协议的框架。
client端
Android IOS Windows MAC Linux 浏览器。
由于不同平台使用了不同的UI库和编程语言,他们的实现差异很大,但是不同的平台都会支持c/c++,所以为了适配不同的平台,WebRTC提供了SDK层,Linux平台基于使用GTK的c++,MAC和IOS平台基于使用cocoa库的Object c,android平台基于JAVA,为了让这些平台都能够调用c/c++核心函数,WebRTC提供了android和object c的封装层,这称为SDK层,android中使用了JNI机制使得UI层的JAVA程序和实现核心功能的c/c++程序可以互相调用,类似的object c使用了.mm扩展程序是得UI的.m程序可以和c/c++互相调用。由于访问各个平台都提供了C API(为了效率),所有已在音视频以及网络API都可以直接通过包含不同操作系统的头文件来实现跨平台差异化编译。
WebRTC官方工程里包括了一些应用程序例子,它们位于src/examples目录下,首先看下各个目录的作用。
peerconnection:windows和linux平台下使用Native API进行P2P通信的例子,其中客户端应用程序在client目录,服务器端应用程序在server目录下。客户端具有简单的音视频功能,服务器端使得客户端程序能够通过信令开启会议。整个会议过程需要服务器先启动服务,如./peerconnection_server --port=8888,正确启动后会有如下输出:
Server listening on port 8888
然后启动客户端,客户端UI包括如下部分,connecting to a server:在客户端程序启动时,需要指定服务器IP地址,然后可以点击connect按钮;其中localhost表示本机地址。
select a peer:当不同的client端连接到server时,他们就会互相发现对方如下所示(这是因为两个client是在同一个电脑不同终端启动的,所以两边看到的都是gsc@240),这是可以直接双击或者选中后回车建立P2P连接;
视频会议:当成功建立端到端的链接后,桌面会以全屏的形式显示视频界面,如下;
Ending chat session:当按Esc键时会推回到P2P列表选择界面;
Ending connection:继续按Esc将回到server连接界面;
工程编译
export PKG_CONFIG_PATH=$WEBRTCBUILDS_FOLDER/lib/Release/pkgconfig
Go to the peerconnection server folder
g++ -o peerconnection_server main.cc data_socket.cc peer_channel.cc utils.cc \
( p k g − c o n f i g − − c f l a g s − − l i b s −