Web即时通信技术——WebRTC

WebRTC(Web Real-Time Communication)是一个开放的项目,旨在在网页端提供实时的音频、视频和数据通信,不需要插件或其他附加软件。它是由Google主导,并在Mozilla、W3C和IETF等组织的支持下开发。WebRTC的目标是使浏览器成为实时通信的强大平台,支持点对点(peer-to-peer)通信。

官方网址:https://webrtc.org/
WebRTC中文网 https://webrtc.org.cn
WebRTC官网 https://webrtc.org/
WebRTC范例 https://webrtc.github.io/samples/

WebRTC特点

实时通信: WebRTC专注于实时通信,包括音频、视频和其他数据。 WebRTC允许从设备中捕获音频和视频流,并在对等连接中传输这些流。WebRTC已经被现代浏览器(如Chrome、Firefox、Safari等)广泛支持,使得开发者能够在Web应用中集成实时通信功能。

点对点通信: WebRTC支持点对点通信,即在两个浏览器之间直接建立连接,而不需要通过中间服务器,不需要插件或其他附加软件。

多媒体引擎: WebRTC包括一个多媒体引擎,用于处理音频和视频流,提供了丰富的API和协议。

NAT穿越和防火墙遍历: WebRTC提供了一些机制,使得在NAT(Network Address Translation)和防火墙等网络设备背后进行通信更为容易。

WebRTC的网络拓扑结构

Mesh 结构

在这里插入图片描述

如果两个Client端能够顺利建立P2P 的连接,则直接通过 P2P 互相交换数据;如果由于网络原因,无法打通,则利用 Turn Server 来中转数据。图中的TURN Server 是指支持 TURN 协议的服务器,它扮演着一种网络中继的角色,支持把一个 Client 的数据包透明转发到多个其他的 Client 客户端。同理也可得出一对一的网络模型。

这种完全使用 P2P 方式的网络拓扑结称之为 Mesh 结构。

这种结构的优点在于逻辑简单,容易实现,较为轻量的服务端,TURN 服务器比较简单,一定比例的P2P 成功率可极大减轻服务端的压力。
缺点在于每新增一个客户端,所有的客户端都需要新增一路数据上行,客户端上行带宽占用太大。因此,通话人数越多,效果越差。

SFU通话模型

在这里插入图片描述
SFU 的全称是:Selective Forwarding Unit,它是一种通过服务器路由和转发 WebRTC 客户端音视频数据流的方法。

SFU 服务器将自己伪装成了一个WebRTC 的 Peer 客户端,WebRTC 的其他客户端其实并不知道自己通过 P2P 连接过去的是一台真实的客户端还是一台服务器,我们通常把这种连接称之为 P2S,即Peer to Server。

SFU服务器和TURN服务器的不同在于:
TURN 服务器仅仅是提供的一种辅助的数据转发通道,在P2P不通的时候进行透明的数据转发。而 SFU 是和客户端有业务交互的,两者是平等的关系,甚至是可以对WebRTC 客户端的数据转发的申请和控制。

MCU通话网络模型

在这里插入图片描述

MCU 的全称是:Multipoint Control Unit,又被称为混合,是实现多方WebRTC交流的另一种策略。
它的主要原理是由 MCU Server 将各路客户端上行的数据流合成为一路,再转发给其他客户端。这种模型相比于 SFU 降低了多人视频通话场景下客户端的下行带宽压力,但是由于合流需要转码操作,因此对服务器端压力比较大,且下发给客户端是固定的合流画面,灵活性不好。

WebRTC 实现服务端和客户端交互的代码

在 Linux 环境下使用 WebRTC 实现服务端和客户端交互的代码一般较为复杂,需要使用信令服务器进行 SDP 交换,并处理 ICE 候选等操作。下面例子是一个简化的代码,使用 WebSocket 作为信令服务器。

创建信令服务器

#include <iostream>
#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/server.hpp>
#include <webrtc/api/peerconnectioninterface.h>class WebSocketServer {
public:WebSocketServer() {server_.init_asio();server_.set_message_handler(bind(&WebSocketServer::OnMessage, this, ::_1, ::_2));server_.set_open_handler(bind(&WebSocketServer::OnOpen, this, ::_1));server_.set_close_handler(bind(&WebSocketServer::OnClose, this, ::_1));}void Run(uint16_t port) {server_.listen(port);server_.start_accept();server_.run();}private:void OnMessage(websocketpp::connection_hdl hdl, websocketpp::server<websocketpp::config::asio>::message_ptr msg) {std::string message = msg->get_payload();// Handle incoming message (Signaling, SDP exchange, etc.)// Example: Forward the message to the appropriate WebRTC peer connection}void OnOpen(websocketpp::connection_hdl hdl) {// Handle new WebSocket connection}void OnClose(websocketpp::connection_hdl hdl) {// Handle WebSocket connection close}websocketpp::server<websocketpp::config::asio> server_;
};int main() {WebSocketServer ws_server;ws_server.Run(9000); // Run WebSocket server on port 9000return 0;
}

客户端

#include <iostream>
#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/client.hpp>
#include <webrtc/api/peerconnectioninterface.h>class WebSocketClient {
public:WebSocketClient() {client_.init_asio();client_.set_message_handler(bind(&WebSocketClient::OnMessage, this, ::_1, ::_2));client_.set_open_handler(bind(&WebSocketClient::OnOpen, this, ::_1));client_.set_close_handler(bind(&WebSocketClient::OnClose, this, ::_1));}void Connect(const std::string& uri) {websocketpp::lib::error_code ec;client_.get_alog().write(websocketpp::log::alevel::app, "Connecting to " + uri);client_.connect(uri, ec);if (ec) {client_.get_alog().write(websocketpp::log::alevel::app, "Error connecting: " + ec.message());}}void Send(const std::string& message) {websocketpp::lib::error_code ec;client_.send(hdl_, message, websocketpp::frame::opcode::text, ec);if (ec) {client_.get_alog().write(websocketpp::log::alevel::app, "Error sending message: " + ec.message());}}private:void OnMessage(websocketpp::connection_hdl hdl, websocketpp::client<websocketpp::config::asio>::message_ptr msg) {std::string message = msg->get_payload();// Handle incoming message (Signaling, SDP exchange, etc.)// Example: Forward the message to the appropriate WebRTC peer connection}void OnOpen(websocketpp::connection_hdl hdl) {client_.get_alog().write(websocketpp::log::alevel::app, "WebSocket connection opened");hdl_ = hdl;// Perform necessary setup, e.g., create WebRTC peer connection}void OnClose(websocketpp::connection_hdl hdl) {client_.get_alog().write(websocketpp::log::alevel::app, "WebSocket connection closed");// Perform necessary cleanup}websocketpp::client<websocketpp::config::asio> client_;websocketpp::connection_hdl hdl_;
};int main() {WebSocketClient ws_client;ws_client.Connect("ws://localhost:9000"); // Connect to WebSocket server on localhost:9000ws_client.Send("Hello, WebSocket!"); // Send a message// Continue with WebRTC logic, e.g., setting up peer connection, SDP exchange, media stream control, etc.return 0;
}

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

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

相关文章

IOS-生命周期-Swift

目录 App生命周期应用状态未运行——Not running未激活——Inactive激活——Active后台——Backgroud挂起——Suspended 关系图生命周期方法相关方法注意在其他地方监听 ViewController生命周期UIView生命周期 App生命周期 应用状态 App主要有五种状态&#xff0c;分别是&…

C++版QT:鼠标事件

鼠标常用的事件可以说有一下几种&#xff1a;鼠标按下、鼠标移动、鼠标移动、鼠标双击和鼠标滚轮事件。 当你想使用他们&#xff0c;需要包含头文件&#xff1a;#include <QMouseEvent> 需要对鼠标事件进行处理时&#xff0c;通常要重新实现以下几个鼠标事件处理函数&a…

什么是 metadata(元数据、meta、metadata、诠释资料、元资料)

我们首先看一下维基百科的介绍&#xff1a; 元数据&#xff08;Metadata&#xff0c;又译作诠释资料&#xff0c;元资料&#xff09;&#xff0c;是一群数据&#xff0c;其内容提供了有关于另一群数据的信息。英文前缀词 meta- 的意思是之后&#xff0c;进而有超出界限&#x…

牛客网-----跳石头

题目描述&#xff1a; 一年一度的“跳石头”比赛又要开始了! 这项比赛将在一条笔直的河道中进行&#xff0c;河道中分布着一些巨大岩石。组委会已经选择好了两块岩石作为比赛起点和终点。在起点和终点之间&#xff0c;有N块岩石(不含起点和终点的岩石)。在比赛过程中&#xff0…

第9章-网络设备基本调试

1. 网络连通性测试 ping命令 定义&#xff1a;基于ICMP协议开发的应用程序&#xff0c;检测网络连通性&#xff1b; 功能&#xff1a; ① 检测网络连接的状态&#xff1b; ② 检测目标计算机是否在线&#xff1b; ③ 定位故障排除&#xff1b; ④ 检测网络延迟和丢包情况&#…

AI智能分析网关V4车辆检测算法及车辆结构化数据在车辆智能管控中的应用

AI边缘计算智能分析网关V4车辆检测、车牌识别算法融合了ORC识别、云计算、计算机视觉、大数据检索等多种技术&#xff0c;可将运动中的机动车牌照从复杂的背景中提取并识别出来&#xff0c;通过车牌提取、图像预处理、特征提取、车牌字符识别等流程&#xff0c;识别出车辆牌号、…

视频监控平台EasyCVR增加fMP4流媒体视频格式及其应用场景介绍

近期我们在视频监控管理平台EasyCVR系统中新增了HTTP-FMP4播放协议&#xff0c;今天我们就来聊聊该协议的特点和应用。 fMP4&#xff08;Fragmented MPEG-4&#xff09;是基于MPEG-4 Part 12的流媒体格式&#xff0c;是流媒体的一项重要技术&#xff0c;因为它能通过互联网传送…

Linux异宠动物园,平面设计篇,Linux平台常见的开源平面设计软件

Linux异宠动物园&#xff0c;平面设计篇&#xff0c;分布介绍视频&#xff0c;讲解了Linux平台常见的开源平面设计软件。如Inkscape&#xff0c;Gimp&#xff0c;Krita&#xff0c;Scribus&#xff0c;并介绍了平面设计行业早期的历史和Aldus公司的历史。 视频请见&#xff1a…

Docker数据管理-容器数据卷

Docker数据管理-容器数据卷 文章目录 Docker数据管理-容器数据卷什么是容器数据卷使用数据卷安装mysql具名挂载和匿名挂载 什么是容器数据卷 数据卷是一个可供容器使用的特殊目录&#xff0c;它绕过文件系统&#xff0c;可以提供很多专用的特性&#xff1a; 数据卷可以在容器之…

Python对分段函数求导+绘制位移s-t、速度v-t、加速度a-t曲线

import matplotlib.pyplot as plt import numpy as np import sympy as spfrom sympy.utilities.lambdify import lambdify #-----------------------------连续数值离散化-便于绘图------------------------------------ def Curve_values(piecewise_function):derivative_fun…

C语言float 类型数如何与0值⽐较?

一、问题 写出 float a 与“0值”⽐较的if语句。 二、解答 1、问题分析与解答 ⼀般地&#xff0c;如果⽤证判断⼀个数值型变量(short、int、long 等)&#xff0c;应该⽤ if(a0)&#xff0c;表示的含义是a与0进⾏“数值”上的⽐较; 但 float 型变量并不精确&#xff0c;不能直…

字符串冲刺题(算法村第十二关黄金挑战)

最长公共前缀 14. 最长公共前缀 - 力扣&#xff08;LeetCode&#xff09; 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀&#xff0c;返回空字符串 ""。 示例 1&#xff1a; 输入&#xff1a;strs ["flower","flow"…