【WebRTC】适合新手宝宝的WebRTC入门教学

文章目录

  • 简述
  • SDP
  • NAT
    • NAT的分类
      • 完全圆锥型
      • 受限圆锥型
      • 端口受限圆锥型
      • 对称型
  • ICE
  • STUN
  • TURN
  • 总结
  • 参考链接

简述

WebRTC通过整合现有的网络协议为设备提供了实时通信的能力,其底层由 C++ 开发,并通过标准化的 JavaScript API 和原生接口(如 C++ 和 Java)向开发者开放。往大了说,WebRTC 实现了一整套支持实时通信的协议和方法。往小了说,WebRTC作为工具为开发者提供了快速开发实时通信系统的一套API。

由于WebRTC具有实时通信的特点,所以其广泛应用于音视频通话、视频直播、电话会议等领域。

接下来我们将一步一步讲解两台身处异地的设备是如何建立双向连接的,在这个过程会遇到许多问题,我们一起看看WebRTC是如何利用现有协议去解决的。

SDP

在因特网中可以通过目标设备的IP+端口向其发送数据,所以想要实现两台设备间的通信就需要互相都知道对方的IP端口。那么如何在茫茫人海中找到她呢,此时可以引入一个中间服务器(信令服务器),想要通信的双方在这个服务器上注册自己并互相发送自己的IP端口等信息。此后双方都知道了对方的IP端口信息就可以实现双向通信。

除了IP和端口信息,通信的双方还需要知道更多,比如说要传递音视频信息,双方要保证一样的编解码方式才可以保证数据在传输后能正常显示。因此WebRTC采用SDP(会话描述协议)用来描绘需要交换的信息,SDP类似JSON/XML只是规定了一种格式,它能够简单明了的表达通信双方想要传达的基本信息,例如音视频编码、地址信息等。

v=0
o=- 0 0 IN IP4 127.0.0.1
s=-
c=IN IP4 127.0.0.1
t=0 0
m=audio 4000 RTP/AVP 111
a=rtpmap:111 OPUS/48000/2
m=video 4002 RTP/AVP 96
a=rtpmap:96 VP8/90000

以上是SDP的一个示例,可以发现每行都由单个字符开始后接“=”,我们称之为Key。SDP规定了固定的key,常用的如下:

  • v - Version,版本,版本,应等于 0。
  • o - Origin,源,包含一个唯一 ID,用于重新协商。
  • s - Session Name,会话名称,应等于-。
  • t - Timing,时间,应等于 0 0。
  • m - Media Description(m=<media> <port> <proto> <fmt> ...),媒体描述。
  • a - Attribute,属性,一个自由文本字段,这是 WebRTC 中最常见的行。
  • c - Connection Data,连接数据,应等于 IN IP4 0.0.0.0

像我们如果想携带自身的IP端口信息就可以写在a=candidate后,这里不做过多的叙述,相信大家也记不住,在遇到的时候再去查就好。

NAT

到这里似乎都一切顺利,然而事情并不简单。在真实的网络环境中,设备发送的数据都会经过网关转发,设备实际使用的是处于局域网中的内部IP,这是因为IPv4地址短缺导致的。设备到公网的流量,都需要经过内网IP到外网IP的转换,这就是NAT(网络地址转换)。这使得我们上面所讲的通信方式无法实现,因为对于设备而言它只知道自己的内网IP,并不知道自己的消息去到公网后的IP,所以无法将自己的IP通过信令服务器告知对方。接下来我们来看看NAT主要做了哪些工作,以此找到实时通信的突破口。

NAT通常作用于路由器,它实际维护了一张内部IP与外部IP的映射表,当设备向外部发送数据时,NAT首先会查询是否有此源地址的记录,如果没有就会为其分配一个端口并创建一条映射,此时数据包的源地址会修改为路由器IP+端口,目的地址不变。当目的地址回包时,路由器进行查表,转发到对应的内部设备
在这里插入图片描述由此我们可以找到突破口,只要能想办法告知对方设备经过NAT转换后的公网IP,建立实时通信就有希望成功。

我们首先考虑最简单的情况,假设:数据经过NAT由x.x.x.x:1001发送后,所有目的地址为x.x.x.x:1001回包均被NAT接受并转发到内部设备

在这个前提条件下,双方建立连接的步骤如下:

  1. 引入中间服务器,服务器功能为返回请求者其公网IP
  2. 设备A与设备B向中间服务器发起请求,获取到自身的公网IP
  3. 设备A与设备B通过信令服务器交换各自信息
  4. 设备A向设备B发送数据,由于设备B已经和中间服务器建立了NAT映射,此时A的数据能通过NAT到达B

NAT的分类

真实的NAT并不会像我们假设的一样简单,不同类型的NAT对映射生成、数据接收有不同的方式。

完全圆锥型

对于内部所有通过同一IP端口发送的请求,均映射为相同的外部IP端口,并且任何外部主机均可以通过映射的外部IP端口向内部主机发送数据。也就是我们上面提到的最理想的状态,这种NAT也是安全性最低的。
[图片]

受限圆锥型

对于内部所有通过同一IP端口发送的请求,均映射为相同的外部IP端口,并且只有内网主机之前已经向公网主机发送过数据,此公网主机才可以向内网主机发送数据
[图片]

端口受限圆锥型

对于内部所有通过同一IP端口发送的请求,均映射为相同的外部IP端口,并且在受限圆锥型的基础上,增加了对端口的限制
[图片]

对称型

对称型NAT把同一内网地址和端口到相同地址和端口的所有请求,都映射为一个公网地址和端口。对于上面三种NAT,只要是同一个内网地址端口生成的都是同一个映射。但是对称型,哪怕是同一台内网主机只要请求的地址不同,就会生成不同的映射
在这里插入图片描述

介绍完4种不同类型的NAT,我们可以发现外部主机和位于NAT之后的主机通信的难易程度是:

完全圆锥<受限圆锥型<端口受限圆锥型<对称型

对于圆锥形我们可以用以下步骤建立连接:

  1. 设备A、B分别向中间服务器注册自己的地址
  2. 设备A向中间服务器请求设备B的地址,同时中间服务器同步A的地址给B,此后AB开始尝试互相发送数据包
  3. 设备A向B第一次发送数据,由于此时B的NAT还没有映射,此时数据会被丢弃
  4. 设备B向A发送请求,此时因为A已经发送过到B的数据生成了NAT映射,所以B能顺利到达A
  5. 设备A第二次向B发送数据,此时由于映射已经建立,数据能正常到达B

对于对称型NAT,由于其不同的目的地址会生成不同的映射,这导致外部设备无法直接与其进行通信,此时需要借助数据中转服务器,这个在后文提到。

ICE

针对上述不同NET类型有不同的建立连接方式,WebRTC是如何处理的呢?我认为这里首先要介绍的就是ICE(交互式连接建立),ICE能够使用各种方法确认两个客户端之间所有可能连接的路由,这些路由被称为:候选地址对。ICE收集到所有路由后会根据算法进行排序,随后通知到设备,设备通过信令服务器交换地址对后进行连通性测试,直到2台设备成功建立连接。我们上诉所讲的中间服务器,实则就是ICE服务器。

候选地址对有多种,其中:

  1. 主机候选对:这就是主机的真实IP和端口,主机候选对可以让通信双方快速确认是否都处于同一个局域网并快速建立连接
  2. 反射候选对:通过STUN获取到的公网IP
  3. 中继候选对:由TURN服务提供的中转流量服务IP

STUN

STUN(NAT 会话穿越应用程序)是一种可以获取位于NAT之后IP,并判断NAT类型的协议。它是一种C/S架构,由客户端发起请求,STUN服务返回其所见的IP也就是设备的公网IP,同时通过STUN可以辨别设备所处的NAT类型
[图片]

以上流程图描述了STUN是如何判断当前NAT属于何种类型:
首先由左上角开始进行测试一,该请求由客户端(设备)发起的普通STUN绑定请求,此时设备如果无法收到回复,说明设备处于的网络禁止了STUN服务,可能整个UDP协议均被禁用。如果设备正常收到了回复,此时可以根据回复中包含的IP地址这里称为:映射地址,来确定一件事,如果映射地址和设备地址相同,说明设备不在NAT之后。

如果设备不在NAT之后,此时进行第二次测试,客户端再次发起请求,但是此时请求需要带上CHANGE-REQUEST改变IP和改变端口标记,这样STUN收到后就会通过不同的映射地址回复请求。此时如果设备收到了回复,说明设备暴露在公网,如果设备收不到回复,说明设备启动了对称型防火墙。

以上UDP被禁用、设备开启对成型防火墙都会导致P2P穿透失败

再次回到测试一,如果设备在NAT之后,进行测试二,如果能收到测试二的回复,说明设备处于完全圆锥型NAT之后。如果收不到测试二的回复,说明设备还有其他可能

此时发起第三次请求,并且需要修改请求的目的地址,此时检查返回的映射地址,如果和最开始做的测试一返回的结果不一致,说明NAT生成了新的映射,也就是对称型NAT。如果返回相同的映射地址,那么还剩最后两种NAT未区分。

最后进行测试3,对发起的请求需要携带CHANGE-REQUEST改变端口标记,此时STUN服务器的响应会修改端口,此时如果设备能收到响应,说明设备位于受限圆锥型NAT,如果收不到响应,说明设备位于端口受限圆锥型NAT

TURN

在特定的情景下,设备无法建立直接的通信,此时需要一台公网的服务器作为中继,对数据进行转发,这就是TURN(NAT 中继遍历程序)。这也是设备双方能建立连接的保底方案,对于ICE来说,TURN服务返回的地址通常优先级是最低的。
[图片]

TURN的工作流程如上图所示:

  1. 设备向TURN服务发起请求,此时TURN能够知道设备的公网地址如图中为:192.0.2.1:7000
  2. 此时TURN会创建一个ALLOCATION用于记录中继地址信息,随后TRUN分配一个中继地址如图中:192.0.2.15:50000
  3. TURN将中继地址返回给设备,设备通过信令服务器告知其他设备,此后其余设备向192.0.2.15:50000发送的数据均会通过TURN转发到192.0.2.1:7000的设备

总结

以上就是WebRTC在建立连接中涉及到的协议介绍,WebRTC整合后的连接流程如下图所示:
[图片]

  1. 通信双方在信令服务器上注册,随后设备生成初步候选地址,这个初步候选地址就是本地的内网地址,然后创建offer,并将初步SDP发送给远端。随后生成候选地址对仍然会继续进行,并不断的通过信令服务器发送给远端。这样做的好处是可以加速连接的建立,在初步sdp发送后就可以开始协商建立连接。
  2. 流程图中的ICE Server包括了STUN、TURN等服务的交互,这里做了简化。实际上,信令服务器和ICE服务器也可以部署在同一台服务器上。
  3. 当双方通过ICE建立连接后,即可开始互相发送数据

参考链接

  • https://webrtcforthecurious.com/zh/docs/03-connecting/
  • https://webrtc.mthli.com/connection/peer-connection/
  • https://www.cnblogs.com/ssyfj/p/14798399.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/485777.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Master EDI 项目需求分析

Master Electronics 通过其全球分销网络&#xff0c;支持多种采购需求&#xff0c;确保能够为客户提供可靠的元件供应链解决方案&#xff0c;同时为快速高效的与全球伙伴建立合作&#xff0c;Master 选择通过EDI来实现与交易伙伴间的数据传输。 EDI为交易伙伴之间建立了一个安…

使用 Cygwin 在 Windows 上开启 ssh 服务器

通常与 Linux 系统打交道多一点&#xff0c;通常连接 Linux 机器时会使用到 ssh 进行连接&#xff0c;并且使用 bash 会更多一点。最近突发奇想&#xff0c;如何在 Windows 上开启 ssh 服务器&#xff0c;使得即使电脑不在身边&#xff0c;也能通过 ssh 连接到远程主机&#xf…

突破空间限制!从2D到3D:北大等开源Lift3D,助力精准具身智能操作!

文章链接&#xff1a;https://arxiv.org/pdf/2411.18623 项目链接&#xff1a;https://lift3d-web.github.io/ 亮点直击 提出了Lift3D&#xff0c;通过系统地提升隐式和显式的3D机器人表示&#xff0c;提升2D基础模型&#xff0c;构建一个3D操作策略。 对于隐式3D机器人表示&a…

docker desktop打包配置国内镜像地址

打包遇到无法访问外网资源&#xff0c;直接配置国内镜像地址 直接加入如下代码就行&#xff1a; {"builder": {"gc": {"defaultKeepStorage": "20GB","enabled": true}},"experimental": false,"registry-m…

MATLAB数学建模之画图汇总

MATLAB是一种强大的数学软件&#xff0c;广泛应用于工程计算、控制设计、信号处理等领域。在数学建模中&#xff0c;MATLAB的绘图功能可以帮助我们直观地展示数据和模型结果。 1. 二维数据曲线图 1.1 绘制二维曲线的基本函数 plot函数用于绘制二维平面上的线性坐标曲线图&am…

喆塔科技携手国家级创新中心,共建高性能集成电路数智化未来

集创新之力成数智之塔 近日&#xff0c;喆塔科技与国家集成电路创新中心携手共建“高性能集成电路数智化联合工程中心”并举行签约揭牌仪式。出席此次活动的领导嘉宾包含&#xff1a;上海市经济和信息化委员会、上海市集成电路行业协会、复旦大学微电子学院、国家集成电路创新中…

2.STM32通信接口之SPI通信---SPI实战《精讲》

SPI仅支持一主多从&#xff08;无应答机制&#xff09; 参照&#xff1a;《第十一部分》1.STM32通信接口之SPI通信---SPI介绍《精讲》-CSDN博客 在采用一主多从的模式下。从机未被选中&#xff0c;SN1时&#xff0c;从机的MISO会处于高阻态状态&#xff0c;SN0时&#xff0c;M…

【Unity 动画】Animation state 动画片段属性面板的解释

1. Motion 描述: 这是分配给该状态的动画剪辑或混合树。 例子: 假设你正在制作一个角色行走的动画。你可以将一个名为“Walk”的动画剪辑拖放到“Motion”属性中。这样&#xff0c;当角色进入“行走”状态时&#xff0c;就会播放“Walk”动画。 2. Speed 描述: 该状态下的动…

Flutter动画(二)内建隐式动画Widget

动画效果介绍中给出了选择动画的决策树&#xff1a; 使用动画框架不在我们讨论的话题内。flutter支持的动画包括隐式动画和显式动画。 隐式动画和显式动画 隐式动画和显示动画是两种不同的动画实现方式&#xff0c;它们的主要区别在于控制权和动画的重复性。 隐式动画&#…

如何解决Redis缓存穿透

如何解决Redis缓存穿透 本篇将带大家了解如何在不同的业务场景下防范Redis缓存穿透&#xff0c;以查询商品业务场景为例子&#xff0c;分别使用缓存null和布隆过滤器的方法来防范缓存穿透 缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在&#xff0c;这样请求到达缓存…

Spring Boot 3.0 + MySQL 8.0 + kkFileView 实现完整文件服务

Spring Boot 3.0 MySQL 8.0 kkFileView 实现完整文件服务 背景&#xff1a;比较常见的需求&#xff0c;做成公共的服务&#xff0c;后期维护比较简单&#xff0c;可扩展多个存储介质&#xff0c;上传逻辑简单&#xff0c;上传后提供一个文件id&#xff0c;后期可直接通过此i…

spring6:3容器:IoC

spring6&#xff1a;3容器&#xff1a;IoC 目录 spring6&#xff1a;3容器&#xff1a;IoC3、容器&#xff1a;IoC3.1、IoC容器3.1.1、控制反转&#xff08;IoC&#xff09;3.1.2、依赖注入3.1.3、IoC容器在Spring的实现 3.2、基于XML管理Bean3.2.1、搭建子模块spring6-ioc-xml…

ROS2创建 base 包用于其他模块的参数配置和头文件依赖

Demo 背景 ROS2项目开发中存在以下需求&#xff1a;有多个包需要读取一些共同的配置项(以txt或者yaml形式存在&#xff09;&#xff0c;且依赖于一些公用的utils工具代码(C)。Solution: 创建一个 base_config 包来“存放” 配置文件和公用的头文件。gitee address: Gitee/CDal…

相机动态/在线标定

图1 图2 基本原理 【原理1】平行线在射影变换后会交于一点。如图所示,A为相机光心,蓝色矩形框为归一化平面,O为平面中心。地面四条黄色直线为平行且等距的车道线。HI交其中两条车道线于H、I, 过G作HI的平行线GM交车道线于M。HI、GM在归一化平面上的投影分别为JK、PN,二者会…

记录下nginx接口代理配置问题

其中api和api1是前面定义的upstream&#xff0c;ip相同只是端口不同。 一开始/api1/直接 像api一样 proxy_pass http://api1这样是不行的&#xff0c;因为会代理到 后端的 /api1/...接口&#xff0c;而后端实际接口地址是 /api/..... 所以必须像上面写法才能将外网的 /api…

【Mac】安装Gradle

1、说明 Gradle 运行依赖 JVM&#xff0c;需要先安装JDK&#xff0c;Gradle 与 JDK的版本对应参见&#xff1a;Java Compatibility IDEA的版本也是有要求Gradle版本的&#xff0c;二者版本对应关系参见&#xff1a;Third-Party Software and Licenses 本次 Gradle 安装版本为…

【JavaEE】多线程(7)

一、JUC的常见类 JUC→java.util.concurrent&#xff0c;放了和多线程相关的组件 1.1 Callable 接口 看以下从计算从1加到1000的代码&#xff1a; public class Demo {public static int sum;public static void main(String[] args) throws InterruptedException {Thread …

Linux-实用操作

文章目录 一. 各类实用小技巧(快捷键)1. ctrl c 强制停止2. ctrl d 退出登出3. history 查看历史命令4. !命令前缀&#xff0c;自动匹配上一个命令5. ctrl r&#xff0c;搜索历史命令6. ctrl a | e&#xff0c;光标移动到命令开始或结束7. ctrl ← | →&#xff0c;左右跳…

李飞飞首个“空间智能”模型发布:一张图,生成一个3D世界 | LeetTalk Daily

“LeetTalk Daily”&#xff0c;每日科技前沿&#xff0c;由LeetTools AI精心筛选&#xff0c;为您带来最新鲜、最具洞察力的科技新闻。 在人工智能技术迅速发展的背景下&#xff0c;李飞飞创立的世界实验室于近期发布了首个“空间智能”模型&#xff0c;这一创新成果引发了3D生…