基于webrtc的数据传输研究总结

什么是webrtc

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

一个简单的例子 PyWebRTC

这里简单介绍一个例子。在这个例子中,建立WebRTC连接的过程如下图所示:
在这里插入图片描述
这是一个简单基于python实现的服务端响应用户请求的例子。当客户端(Client)发起请求,服务器端(Server)与Client建立WebRTC连接,并把流媒体资源库中的demo-instruct.wav音频通过WebRTC连接的方式传输到Client,在Client这一端可以实时听到音频的播放。

RTCPeerConnection

webrtc的P2P连接依赖于实现在两端主体程序中的RTCPeerConnection对象(pc_client和pc_server),它们需要经历两个阶段的协商,才能建立连接。

媒体协商

媒体协商要做的事情,是让彼此了解对方的多媒体能力(上图中红色标记的步骤)。例如:webrtc默认使用V8编码和解码,如果Client不支持V8解码,如果没有媒体协商过程,那么即便是连接成功,Server把视频数据发给Client,对方也无法播放。进一步,如果Client支持VP8、H264多中编码格式,而Server支持VP9、H264,如果要保证两端的正常的编码、解码,最简单的办法是取它们的交集,H264。

媒体协商的过程在代码层实际上是交换了各自的sdp信息,这个过程也叫 offer/answer 过程(可能是因为Client端的sdp信息由createOffer()方法创建,而Server的sdp信息由createAnswer()方法创建)。在这个例子中,这个过程大致为,首先由Client通过普通http请求的方式将自身sdp信息Post给Server,然后Server将自身sdp信息作为响应返回给Client,它们各自使用以下语句,来设置自身的sdp,和对方的sdp。

#用于设置自身的多媒体特征sdp
pc.setLocalDescription()
#用于设置对方的多媒体特征sdp
pc.setRemoteDescription

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)

举例如下:

v=0
o=jdoe 2890844526 2890842807 IN IP4 10.47.16.5
s=SDP Seminar
i=A Seminar on the session description protocol
u=[http://www.example.com/seminars/sdp.pdf](http://www.example.com/seminars/sdp.pdf)
[e](mailto:e=j.doe@example.com)[=j.doe@example.com](mailto:e=j.doe@example.com) (Jane Doe)
c=IN IP4 224.2.17.12/127
t=2873397496 2873404696
a=recvonly
m=audio 49170 RTP/AVP 0
m=video 51372 RTP/AVP 99
a=rtpmap:99 h263-1998/90000
网络协商

当各端调用 setLocalDescription 后,WebRTC就开始建立网络连接,主要包括收集candidate、交换candidate和按优先级尝试连接,该过程被称为ICE(Interactive Connectivity Establishment,交互式连接建立)。其中每个 candidate 都包含IP地址、端口、传输协议、类型等信息。
根据 RFC5245 协议 ,WebRTC将 candidate分为了四个类型:host、srflx、prflx、relay,它们的优先级依次降低。
host:Host Candidate,根据主机的网卡数量决定,一般一个网卡对应一个ip地址,然后给每个ip随机分配一个端口生成。
srflx:Server Reflexive Candidate,根据STUN服务器获得的ip和端口生成。
prflx:Peer Reflexive Candidate,根据对端的ip和端口生成。
relay:Relayed Candidate,根据TURN服务器获得的ip和端口生成。
简单点来说,candidate的交换即告诉对方自己传输数据的方式。在PyWebRTC的这个例子中,candidate的交换是自动完成的。不需要额外编写代码。

以下是当Client和Server在同一个网段下,没有使用turnserver时的candidate信息

在offer中的candidate信息

a=candidate:3508291585 1 udp 2122260223 192.168.36.1 62937 typ host generation 0 network-id 1
a=candidate:3773578447 1 udp 2122194687 172.16.123.63 62938 typ host generation 0 network-id 2
a=candidate:2678043889 1 tcp 1518280447 192.168.36.1 9 typ host tcptype active generation 0 network-id 1
a=candidate:2926559295 1 tcp 1518214911 172.16.123.63 9 typ host tcptype active generation 0 network-id 2

在answer中的candidate信息

a=candidate:ae131dace505164676d6f637ba6d2232 1 udp 2130706431 172.16.123.63 62943 typ host
a=candidate:4f58facbc6fb04d2f88caee9bdc8c3c6 1 udp 2130706431 192.168.36.1 62944 typ host
a=candidate:c23b409001556fce7bcd691e8a5c284f 1 udp 1694498815 113.67.225.115 10944 typ srflx raddr 172.16.123.63 rport 62943

PyWebRTC 与 TurnServer结合的例子

什么是turnserver

在实际情况中,我们更多面临由基于NAT所搭建的网络环境。NAT的用处主要有两个:
(1)解决IPv4地址不够用的问题,可以让多个主机共用一个公网IP。
(2)将主机隐藏在内网中,外网比较难访问到真实主机。
在这种情况下,基于webrtc的Client和Server无法建立对等连接,所以需要依赖turnserver的中继功能来转发,以解决处在不同网络域对等端的连接建立与通讯问题。

使用VMWare和Docker模拟内外网环境

由于缺乏真实的Nat内外网环境,这里使用了两套虚拟网络机制来模拟内外网环境,这里记录一下搭建这套环境的过程。首先安装一个虚拟机(Ubuntu20.04),网络连接选择桥接模式,并且是自动获取ip。
在这里插入图片描述
这种模式下给虚拟机分配的ip会与宿主机(相对于虚拟机)处于同一网段,例如我当前宿主机(相对于虚拟机)的ip为172.16.123.63,而虚拟机的ip为172.16.123.118。这样就会形成一个“外网环境”,并且Client运行在外网环境中浏览器中。

在虚拟机中安装docker,利用docker虚拟网络模拟内网环境。注意创建容器时network_mode不能为host,因为这样将无法控制端口的开放,而在实际情况中,端口默认都是不开放的。创建容器时,docker会默认生成一个虚拟桥接网卡(使用ifconfig可以看到),这个网络与容器里查询到的ip处于一个网段。这样形成了一个“内网环境”。
在这里插入图片描述
如上图所示,在虚拟机中ifconfig查看网络可知,ens33是VMWare的虚拟网卡,br-7261d1118a42是它所安装的docker的其中一个虚拟网卡,可通过docker network ls 查看docker的所有虚拟网卡,如下图所示,这串数字与br-7261d1118a42对应
在这里插入图片描述
进去容器中查看它的ip,如下图所示,可以知道容器ip与虚拟机的虚拟网卡ip在统一网段。
在这里插入图片描述
最后总结,利用VMWare和Docker两套虚拟网络机制模拟的内外网网络环境可以用以下示意图来表示
在这里插入图片描述

创建Server和coturn的镜像并创建容器

由于Server和coturn部署在虚拟内网,而内网由docker模拟,所以Server和coturn需要制作成镜像。

FROM python:3
WORKDIR /usr/src/app
COPY pywebrtc ./
COPY turnserver.conf ./
COPY requirements.txt ./
COPY sources.list ./
RUN mv /etc/apt/sources.list /etc/apt/sources.list.bak \
  && cp ./sources.list /etc/apt/sources.list \
  && apt-get update \
  && apt-get install coturn -y \
  && apt-get install vim -y \
  && apt-get install net-tools \
  && pip install --no-cache-dir -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple \
  #&& openssl req -x509 -newkey rsa:2048 -keyout /etc/sslkey.pem -out /etc/sslcert.pem -days 99999 -nodes \
  && mv /etc/turnserver.conf /etc/turnserver.conf.bak \
  && cp turnserver.conf /etc/turnserver.conf \
  && rm /usr/src/app/turnserver.conf \
  && turnadmin -a -u demo -p 4080218913 -r 172.16.123.118 \
  && turnadmin -l
EXPOSE 8801
EXPOSE 3478
EXPOSE 3478/udp
EXPOSE 9000
EXPOSE 9000/udp
EXPOSE 59000-59010/udp
CMD [ "python", "main.py" ]

如上DockerFile所示,内容包括:
(1)基础镜像是python:3,因为Server是基于aiortc和tornado实现的python应用。
(2)修改镜像中系统软件源为国内源。
(3)安装coturn,vim,net-tools,安装Server运行所需要的依赖。
(3)替换镜像中coturn的配置文件turnserver.conf
(4)开放相关端口,需要对应turnserver.conf中的端口配置。8801端口用于交换sdp媒体描述信息和icecandidate网络信息(icecandidate可以手动设置);3478是tunserver的监听端口,在Client端指定turnserver地址时会用到。9000也是turnserver的监听端口,在turnserver.conf中对应tls-listening-port,使用这个端口会在TLS & DTLS基础上安全传输;59000-59010是turnserver 启动UDP中继通道的端口上下界。
镜像创建结束后,使用docker-compose.yaml创建容器。

version: '3.1'
services:
  pywebrtcturn:
    image: alan/pywebrtcturn:v1
    container_name: pywebrtcturn
    ports:
      - "8801:8801"
      - "3478:3478"
      - "3478:3478/udp"
      - "9000:9000"
      - "9000:9000/udp"
      - "59000-59010:59000-59010/udp"

    # network_mode: "host"

turnserver的配置和启动

使用docker-compose.yaml创建容器后,进入容器,使用以下命令创建公钥和秘钥

openssl req -x509 -newkey rsa:2048 -keyout /etc/sslkey.pem -out /etc/sslcert.pem -days 99999 -nodes

创建用户,但是在我们的例子里,这一步已在DockerFile里完成,进入容器后可以忽略这一步

turnadmin -a -u demo -p 4080218913 -r 172.16.123.118

设置turnserver的配置,/etc/turnserver.conf,如下所示

listening-ip=172.18.0.2
listening-port=3478
tls-listening-port=9000
relay-ip=172.18.0.2
relay-threads=50
external-ip=172.16.123.118
min-port=59000
max-port=59010
lt-cred-mech
Verbose
fingerprint
cert=/etc/sslcert.pem
pkey=/etc/sslkey.pem
realm=172.16.123.118
no-loopback-peers
no-multicast-peers
mobility
no-clis

这里需要特别注意几个ip的设置,listening-ip、relay-ip和external-ip等等,需要结合上面虚拟内外网网络环境的示意图来对应。几个端口的设置则要结合DockerFile和docker-compose.yaml来设置。

启动turnserver

turnserver

如何使用turnserver

在前端页面作iceserver的配置便可

config.iceServers = [{url: 'turn:172.16.123.118:3478',username:"demo",credential:"4080218913"}];

在页面中点击start,等待一下,便可听到处于虚拟内网中Server返回的多媒体资源。

注意:turnserver有turn和stun两种方式,但是我用stun只成功了一次,我猜测是stun机制下配置中的min-port和max-port并没有生效,中继通道所使用的端口并没有控制在容器创建时预期的59000-59010范围内。

研究总结

我研究webrtc的过程中有几个要点
(1)webrtc p2p通信指的是两侧的RTCPeerConnection对象,但是建立连接时需要帮助它们交换sdp媒体特征描述信息以及icecandidate网络传输信息,这一步可以基于用多种方式来实现。
(2)如何在有限的条件下模拟内外网环境。
(3)turnserver配置要准确,要清楚内网ip和外网ip具体分别指的是什么,要有一定的网络基础。

基于websocket实现的webrtc连接

待更新

webrtc相关概念详细说明

待更新

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
基于WebRTC的多人视频会议系统是一种通过Web浏览器实现的即时通讯系统。该系统允许多个用户通过互联网同时进行视频会议和实时交流,无需安装额外的软件或插件。 WebRTC基于一组实时通信协议,包括音视频传输、网络连接和通信控制等。通过利用WebRTC技术,系统可以实现低延迟的音视频传输和高质量的音视频通信,为用户提供更加沉浸式和真实的会议体验。 在多人视频会议系统中,用户可以通过浏览器访问系统网站,并通过输入会议号或邀请链接加入到会议中。系统会自动检测用户设备的音视频设备并进行配置,以确保用户在会议中能够正常进行音视频通信。 在会议中,用户可以选择开启或关闭自己的摄像头和麦克风,实现视频和音频的双向交流。系统会将用户的视频流实时传输给其他与会者,并显示其他与会者的视频流。此外,系统也提供文本聊天功能,方便用户进行实时的文字交流。 多人视频会议系统还允许用户共享屏幕,以便在会议中展示自己的电脑桌面、文档或应用程序。此外,系统还支持会议录制和回放功能,方便用户进行会议内容的保存和回顾。 基于WebRTC的多人视频会议系统提供了一个高效便捷的方式,让用户能够方便地进行远程会议和协作。无论是商业会议、在线培训还是团队协作,该系统都能满足用户的实时通信需求,并提供良好的用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值