百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

WebRTC → 多人通讯架构浅析

toqiye 2025-01-19 00:24 487 浏览 0 评论

一对一通信模型

一对一通信中,WebRTC会先尝试两个终端之间是否可以通过P2P直接进行通信,无法通信时会通过STUN/TURN服务器进行中转;其中STUN/TURN服务器的作用在不能直连时是中继服务器,通过该服务器进行端到端之间的数据中转;当可以直连时STUN/TURN的作用就只是用于各端收集reflx类型的Candidate; 原则是尽可能让双端进行直连,这样既可以节省服务器的资源,又可以提高音视频服务器的质量;

  • 1v1通信连接过程图解

即是端A与端B之间的Offer信息的本地存储与远端发送,从而打通双端的基本信息交换

通信架构分析

P2P

端与端之间直接通信,适合两人通信场景,可以理解成Mesh,Mesh是标准P2P通信模式的混用

Mesh方案/架构

多个终端之间共享媒体数据时需要同时向其他端发送对应的数据;

TURN Server是指支持TURN协议的服务器,扮演者一种网络中继的角色,支持将一个client的数据包透明的转发到多个其他的Client客户端

C++音视频学习资料免费获取方法:关注音视频开发T哥,点击「链接」即可免费获取2023年最新C++音视频开发进阶独家免费学习大礼包!

图解Mesh架构图

  • 终端浏览器之间两两相连,还分别与STUN/TURN服务器进行连接,此时STUN/TURN服务器不会进行数据中转;
  • 单方面进行音视频数据共享时,需要将共享的数据分别发送给其他端,从而实现多人通信
  • 优势
    • 不需要服务器中转数据,STUN/TURN只负责NAT穿越,不需要再单独开发一套美体服务器,利用现有的WebRTC通信模型就可以实现
    • 充分利用了客户端的宽带资源
    • 节省服务器资源,不需要其他的数据处理和中转
    • 基础的信令服务器还是要用的
  • 劣势
    • 当有过多的终端进行音视频流共享的时候,需要向每个终端进行共享,此时占用的宽带、CPU、Memory等资源也就不断变大,一般人数超过4人时就会出现问题
    • Mesh架构是依赖于大多数终端都可以直连的情况下的,当有终端不能实现NAT穿越时就会出现较复杂的打通逻辑
    • 每新增一个客户端,所有客户端都需要新增一路数据上行,客户端上行带宽占用太大,通话人数越多,效果越差

MCU方案/Mixer架构

接收每个共享端的数据时会进行解码、与其他端解码后的数据进行混合,重新编码,之后再讲混合后的音视频数据发送给房间内的所有人; 是在SFU的基础上将多路流在服务器进行合流后再转发给终端,从而将多路下行合并成一路下行流,进一步减少宽带,但会增加服务器压力


图解MCU方案

MCU方案中的MCU(多点控制单元:接收并混合每个客户端传入的媒体流-将多个客户端的音视频画面合成单个流,再传输给每个参与的客户端)相当于是中转器,将共享者发送的数据进行解码、混合、编码等操作后将数据发送给接收端,同时共享端之间也是将除本端的数据外都进行不处理直接推送到各发送端;

MCU处理逻辑图

  • 处理过程分析
    • 接收共享端发送的音视频流数据
    • 解码接收到的音视频流数据
    • 对视频流进行重新布局、混合处理
    • 对音频流进行混音、重采样处理
    • 将混合后的音视频进行重新编码
    • 将编码后的数据发送给客户端
  • 优点
    • 缓解了Mesh架构中的问题(多端时宽带压力较大)
    • 非常成熟,在硬件音视频会议中应用广泛
    • 通过重新的编解码和数据流二次操作可以适配更多的终端
    • 通过将多共享端的数据混合成一路,可以使得所有人看到的数据是相同的画面,同时对客户端的压力也是最小的
  • 劣势
    • 对数据流的编解码和二次处理会加大对CPU网络的消耗,且更容易导致视频流的延迟
    • 对服务器压力最大:
      • 需要提供一个中心化的MCU混流服务器,所有媒体流的解码、编码、转码、混合都在服务器端完成
    • 自定义布局复杂:
      • 一般情况下MCU服务器仅混合编码一路合并后的媒体流,不论有多少参会者,看到的画面都是一致的,要想某个人想改变视频画面布局,比如放大或关闭某一人的视频画面通常是无法满足的,除非定义单独的信令逻辑,请求MCU服务器单独编码一路流发送给特定需求的参会者;

SFU方案/Router架构

SUN可以理解成一个路由器,接收终端的音视频流,再转发到其他终端,支持WebRTC的媒体服务器基本都是SFU结构; SFU结构中的每个终端都会共享一路流分发给SFU,SFU会将每一路流都转发给除共享者之外的其他端; 全称是Selective Forwarding Unit,终端只需发送一路上行流到服务器,通过服务器俩路由和转发给其他终端,避免mesh中终端多路上行产生的宽带压力

  • 和Mixer架构类似,只是Router架构只是单纯的进行数据流的转发,不用合成、转码等操作;
  • SFU会根据终端下网络状况做一些流控,可以根据当前宽带情况,网络后延迟时会选择性的丢弃一些媒体数据,保证数据的连续性
  • 优势
    • 数据包是直接转发,不需要解码、编码等操作,对CPU等资源的消耗小;,服务器压力和成本降低
    • 直接转发也极大的降低了延迟,提高实时性;
    • 具有灵活性,多路媒体流可以进行自定义
  • 劣势
    • 由于数据包直接转发,参与人观看多路流可能会出现不同步,相同的流也有可能画面不一致
    • 客户端加码压力大:
      • 每个客户端需要解码n-1路媒体流,和Mesh架构类似

如何实现SFU

SFU的职责之一是接收和发送RTCP数据包,RTCP数据包包括关于音频和视频流的不同类型的反馈,且最重要的RTCP数据包时接收器报告(RR:数据包从媒体流接收器发送到该媒体流的发送者); 在SFU情况下,RR由SFU产生,并发送到媒体流发送器,并且还从每个流接收器发送到SFU;

SFU的核心功能是基于WebRTC protocol与终端建立连接,接收终端上传的视频流,并将其转发给其他终端 - 重点在于实现WebRTC protocol的能力,可以将其拆解为两部分工作:

  • 信令服务:在SFU服务器与终端之间传输WebRTC protocol中的SDP数据和ICE数据,提供简历WebRTC连接的相关信息
  • 流媒体服务:在SFU服务器与终端之间基于WebRTC protocol传输视频流数据

信令服务

信令服务需要传递的SDP和ICE两种数据,但SDP又分为Offer和Answer两类数据,所以需要提供三个信令

  • 三个信令
    • Offer
    • Answer
    • Candidate
  • 信令格式是JSON格式,两个字段,一个表示区分信令,另一个字段携带数据
type Message struct { 
    Event string `json:"event"` 
    Data string `json:"data"` 
}
  • WebRTC客户端与SFU服务器需要协商的点
    • ICE建联:交换ICE信息(用户名、密码、IP地址、UDP端口等)
    • 发布流/取消发布流(Publish):客户端通知服务器准备好接收数据
      • Publish:添加一个逻辑上的Producer,通过UDP通道recv客户端的数据,通知逻辑上的Consumers
    • 订阅流/取消订阅流(Subscribe):客户端通知服务器准备好转发数据
      • Subscribe:添加一个逻辑上的Consumers,接收到Producer通知后,通过UDP通道send给客户端
  • 传输协议选择WebSocket
  • 实现one-to-more,最主要的就是将数据的生产者和消费者关联起来,关联方法就是通过RTP包头中的xxxC(同步源标识)
    • WebRTC传输的音视频数据,实际是封装在RTP包里面
    • 实现one-to-more的核心代码逻辑抽象是:SFU接收到Publish发送上来的数据后,轮训一下所有的Subscribers,如果xxxC匹配成功后,则将数据转发给这个客户端

流媒体服务

流媒体服务需要实现WebRTC protocol中定义的connectioning,securing,communicating的能力,需要用到pion库,其已经提供了使用golang实现的WebRTC protocol,其主要接口已WebRTC API基本一致

Simulate模式

是指视频的共享者可以同时向SFU发送多路不同分辨率的视频流(一般为3路流,1080P、720P、260P),而SFU会根据各端的情况选择一路流发送出去;

SVC模式

SVC是可伸缩的视频编码模式,与Simulate模式的同时传多路流不同,SVC模式是在视频编码时做手脚; 在视频编码时将视频分为多层,核心层、中间层和拓展层,上层依赖下层,越上层越清晰,在网络较好时可以将三层都发送出去,不好时将最底层发送出去;

总结

SFU是三种架构方案中优势较明显而劣势相对较少的一种架构方案 SFU相比于MCU,服务器的压力更小(纯转发,无转码合流),灵活性更好(可选择性开关任意路数据的上下行等),受到更广泛的欢迎和使用,当然在更复杂的生产环境下可能会将SFU和MCU会混合使用

多端通信

原理分析

常规的直播基本属于1V多,只有一端输出视频流,其他端只需要接收就好,这种方式一般通过服务端进行媒体流的转发

注意事项

  • 如何给每个客户端创建多个点对点连接
    • 两两之间的连接都是单独创建的Peer实例,从而保证每个端之间的Peer是一一对应的
  • 如何保证连接的顺序性
    • 在1v1中明确的存在呼叫端和接收端
      • 1v1中创建Peer实例的时机是:接收端点击同意通话后,初始化自己的Peer实例;呼叫端接收到对方同意申请的通知后,初始化自己的Peer实例,并向其发送Offer
    • 在多人直播的场景中规定后加入房间的成员向房间内所有已加入的成员分别发送Offer,以此保证时序性

拓展

WebRTC - SFU - 推流简介

  • 大体流程
    • 通过STUN协议获取对方的公网IP和端口
      • STUN(Simple Traversal of User Datagram Protocol Through Network Address Translators),即简单的通过UDP穿越NAT,是个轻量级的协议,是基于UDP的完整的穿透NAT的解决方案;
      • NAT穿透(NAT Traversal):在进行P2P通信之前,需要进行检测以确认主机之间能否进行P2P通信以及如何通信,这种技术称为NAT穿透
      • STUN协议主要做了两件事:检测NAT类型和获取NAT分配的公网IP和端口
    • 通过DTLS协议进行握手,设置加密信息等
    • 通过RTP和RTCP协议进行数据的传输和数据状态的上报和获取

推荐文献

前端实现多人视频聊天

作者:FE杂志社 链接:https://juejin.cn/post/7188127733271953469 来源:稀土掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

相关推荐

Star 17.3k!给它一张屏幕截图,即可一键克隆网页!

本文为大家分享一款本周爆火的GPT开源项目。前言你敢信,只凭借着一张屏幕截图即可转换生成HTML/TailwindCSS代码。可以算得上是前端工程师的福音。它就是screenshot-to-...

AI从截图直接生成代码、前端程序员的福利!

简介项目可以将任何屏幕截图或设计转换为干净的代码(支持大多数框架)。来自领先公司的开发人员和设计师使用的排名第一的工具。完全开源,在GitHub上拥有超过35,000颗星。非常受欢迎。各位小伙...

一款高颜值、跨平台、自托管的免费开源CRM项目——Twenty

前言大家好,这里是可爱的Cherry。作为一个“甲方”,Cherry其实挺知道客户管理的重要的。但是对于客户管理怎么做,以及CRM的作用,我却是一无所知。之前有朋友在评论区留言,说有没有开源的CRM系...

解放双手,前端界面再也不用自己写了?

随着AI技术的发展,现在有越来越多的尝试将AI应用于UI设计和开发中,以期提高效率和降低成本。今天就给大家介绍一个开源的AI网页生成工具:OpenUIOpenUIOpenUI是一个创...

代码调试,教给你(代码调试是什么意思)

昨天我和一些朋友一起调试代码,他们做程序员这一行都不太久,我向他们展示了一些代码调试技巧。今天早上我在想,我应该如何教授他们学习代码调试?我在Twitter上发了一条推文说,我从来没有见过任何好的调试...

Screenshot-to-code:用屏幕截图生成代码

Screenshot-to-code是一个简单的工具,可使用AI将屏幕截图、模型和Figma设计转换为干净、实用的代码。现在支持ClaudeSonnet3.5和GPT-4o!Scre...

next实现原理(next method)

Next.js是一个基于React的服务器端渲染(SSR)和静态生成(SSG)框架,它的实现原理涉及多个关键技术点,包括服务端渲染(SSR)、静态生成(SSG)、客户端渲染(CSR)、...

可逐步操作的具体流程(可逐步操作的具体流程包括)

假设你是一个单人开发者,使用主流技术栈(React+Node.js+MySQL),以下是详细步骤:---###**一、需求分析与原型设计**1.**核心功能清单**-用户能添加、删除、...

截图转代码只需1步!你离高效开发只差这款神器

引言在现代前端开发中,将设计稿转换为代码是一个既重要又耗时的环节。手动编写HTML结构、调试CSS样式、调整布局对齐,不仅耗费时间,还容易出错。而Screenshot-to-Code这款革...

web开发 前端 后端(web开发前端后端)

区别:1、前端是指用户可见的界面,而后端是指用户看不到的东西,考虑底层业务逻辑的实现,平台的稳定性、性能等。2、前端开发用到的技术有HTML5、CSS3、JS、jQuery、Bootstrap、Nod...

手把手教你Dify私有化部署,打造专属AI平台

一、Dify是什么?Dify是一款极具创新性的开源LLM应用开发平台,它就像是一把万能钥匙,为开发者们打开了通往生成式AI应用开发新世界的大门。其融合了后端即服务(BackendasS...

前后端分离架构设计:提升开发效率与业务支撑力的密钥

前后端分离架构设计解析一、定义与核心思想前后端分离是一种将用户界面(前端)与业务逻辑(后端)解耦的架构模式,通过RESTfulAPI或GraphQL实现数据交互。前端专注于视图渲染与交互逻辑...

Kubernetes最小部署单元Pod(kubernetes最小部署单元)

一、Kubernetes与Pod简介在当今云计算和容器化技术盛行的时代,Kubernetes已然成为容器编排领域的中流砥柱。它是一个开源的容器编排平台,由Google基于其内部使用的Bo...

【程序员必藏!零基础本地部署DeepSeek大模型保姆级教程】

为什么选择本地部署?数据安全:敏感代码/业务数据永不外传闪电响应:局域网推理延迟<100ms,告别云端排队深度定制:自由修改模型代码,打造专属AI助手准备工具(5分钟搞定)1核心工具下载...

【Python程序开发系列】使用Flask实现前后端分离(案例)

这是我的第398篇原创文章。一、引言随着web开发的不断发展,前后端分离已成为越来越流行的架构设计。Flask是一个轻量级的Pythonweb框架,非常适合用于构建API,然后配合前端框...

取消回复欢迎 发表评论: