构建WebRTC技术需要的后端服务

  • 📢欢迎点赞 :👍 收藏 ⭐留言 📝 如有错误敬请指正,赐人玫瑰,手留余香!
  • 📢本文作者:由webmote 原创
  • 📢作者格言:新的征程,我们面对的不是技术而是人心,人心不可测,海水不可量,唯有技术,才是深沉黑夜中的一座闪烁的灯塔 !

在这里插入图片描述

序言

当下直播界最炙手可热的技术,WebRTC应该时其中之一,而想在此技术领域登堂入室,确实有很多的知识和积累需要熟悉和学习,作为一个技术新手,怎么从懵懂到会用再到理解内涵而会心一笑,确实是挺难的一件事情。

也许我们永远也无法企及大师的项背,但有一点可以坚信,只要我们努力去学习,会使用这个最简单而直接的要求肯定能达到。

1. WebRTC技术

WebRTC(Web实时通信)是一种开放标准和技术,用于在Web浏览器之间实现实时通信,包括音频、视频和数据传输。它是由Google推出的,并得到了其他大型技术公司的支持和采用,目前众多的浏览器都已经支持WebRTC了,因此其应用也越来越多。

WebRTC的主要特点包括:

  1. 实时通信:WebRTC允许实时的音频、视频和数据传输,使用户可以通过浏览器直接进行语音和视频通话,而无需其他插件或软件。

  2. 网页集成:WebRTC可以直接集成到Web浏览器中,通过JavaScript API进行操作,无需下载或安装额外的应用程序。

  3. 点对点通信:WebRTC支持点对点(peer-to-peer)通信,这意味着数据可以直接在两个浏览器之间传输,而无需通过中间服务器。这种直接的通信方式可以提高速度和减少延迟。

  4. 安全性:WebRTC使用安全的传输协议(如SRTP)来保护音频和视频通信的隐私和安全性。它还支持加密和身份验证,确保通信的机密性和完整性。

  5. 开放标准:WebRTC是一个开放的标准,由W3C和IETF进行标准化和规范化。这意味着它是一个公开的技术,并且可以被广泛采用和支持。

WebRTC技术的特点使其在在线会议、远程协作、客户支持和实时通信应用中得到广泛应用。它提供了一种简单、便捷和安全的方式来进行实时通信,为用户提供了更好的体验和互动性。

2. 信令服务

虽然WebRTC支持点对点通信,但它仍然需要服务器,以便客户端可以交换元数据,通过称为信令的过程协调通信,并处理网络地址转换器(NAT)和防火墙。

这里我们主要介绍如何构建信令服务,以及如何处理与 STUN 和 TURN 服务器进行实际连接的行为。当然它还解释了WebRTC应用程序如何处理多方呼叫并与VoIP和PSTN(也称为电话)等服务进行交互。

如果您不熟悉WebRTC的基础知识,请在阅读本文之前参阅WebRTC入门。

那么,什么是信令呢?

信令是协调通信的过程。

为了使WebRTC应用程序能够配置呼叫,其客户端需要交换以下信息:

  • 用于打开或关闭通信的会话控制消息
  • 错误消息
  • 多媒体元数据,例如编解码器、编解码器设置、带宽和媒体类型
  • 用于建立安全连接的关键数据
  • 网络数据,例如外界看到的主机的 IP 地址和端口

此信令过程需要和客户端来回传递消息,该机制不是由WebRTC API实现的,您需要亲自构建它。

2.1 为什么WebRTC没有定义信令?

为了避免冗余并最大限度地与现有技术兼容,WebRTC标准没有指定信令方法和协议。

JavaScript 会话建立协议 (JSEP) 概述了此方法:

WebRTC呼叫背后的思想是完全指定和控制媒体,尽可能将信令留给应用程序。理由是不同的应用程序可能更喜欢使用不同的协议,例如现有的 SIP 或 Jingle 呼叫信令协议,或者针对特定应用程序自定义的内容。

JSEP 的体系结构还避免了浏览器必须保存状态,即充当信号状态机的功能。例如,如果每次重新加载页面时都会丢失信令数据,这将是一个问题。相反,信令状态可以保存在服务器上,这样看起来架构就更完美了,下图是JSEP体系架构。

在这里插入图片描述

JSEP 要求新的的交换在提问者offer 和 回答者answer之间, 即上面提到的媒体元数据。OfferAnswer以会话描述协议 (SDP) 格式传达,如下所示:

v=0
o=- 7614219274584779017 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE audio video
a=msid-semantic: WMS
m=audio 1 RTP/SAVPF 111 103 104 0 8 107 106 105 13 126
c=IN IP4 0.0.0.0
a=rtcp:1 IN IP4 0.0.0.0
a=ice-ufrag:W2TGCZw2NZHuwlnf
a=ice-pwd:xdQEccP40E+P0L5qTyzDgfmW
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=mid:audio
a=rtcp-mux
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:9c1AHz27dZ9xPI91YNfSlI67/EMkjHHIHORiClQe
a=rtpmap:111 opus/48000/2

想知道所有这些SDP胡言乱语实际上意味着什么吗?可以查看互联网工程任务组 (IETF) 示例。

请记住,WebRTC的设计使得在通过编辑SDP文本中的值设置为本地或远程描述之前可以调整offeranswer。例如,appr.tc 中的函数可用于设置默认编解码器和比特率。

SDP用JavaScript操作起来有些痛苦,并且有关于WebRTC的未来版本是否应该使用JSON的讨论,但是坚持使用SDP也有一些优点。

2.2 Alice呼叫Eve

当Alice想要呼叫Eve时,使用WebRTC的过程大致如下:

  1. Alice打开她的Web浏览器,并通过getUserMedia方法获取她的音频和视频流。这将启动她的摄像头和麦克风。

  2. Alice创建一个RTCPeerConnection对象,这是WebRTC中用于建立对等连接的主要对象。

  3. Alice将她的本地流(音频和视频)添加到RTCPeerConnection对象中。

  4. Alice创建一个数据通道(Data Channel),这是用于在对等连接之间传输任意数据的通道。数据通道可以用于发送文本消息、文件等。

  5. Alice为数据通道设置消息接收的回调函数,以便在收到来自Eve的消息时进行处理。

  6. Alice创建一个offer(邀请),其中包含她的媒体信息和网络配置。这个offer描述了Alice希望与Eve建立连接的条件。

  7. Alice将她的本地描述(offer)设置为RTCPeerConnection的本地描述。

  8. Alice通过信令服务器将她的本地描述发送给Eve。信令服务器充当中介,帮助Alice和Eve交换网络配置和媒体信息。

  9. Eve收到Alice的本地描述,并创建一个RTCPeerConnection对象。

  10. Eve将她的本地流(音频和视频)添加到RTCPeerConnection对象中。

  11. Eve将Alice的本地描述设置为她的RTCPeerConnection的远程描述。

  12. Eve创建一个answer(回答),其中包含她的媒体信息和网络配置。这个answer是对Alice的offer的回应。

  13. Eve将她的本地描述(answer)设置为RTCPeerConnection的本地描述。

  14. Eve通过信令服务器将她的本地描述发送给Alice。

  15. Alice收到Eve的本地描述,并将其设置为她的RTCPeerConnection的远程描述。

  16. Alice和Eve的RTCPeerConnection对象之间开始进行ICE(Interactive Connectivity Establishment)协商,以确定最佳的网络连接路径。

  17. 一旦ICE协商完成,Alice和Eve之间的对等连接建立成功,他们可以通过数据通道交换消息、音频和视频。

总的来说,WebRTC通过使用RTCPeerConnection对象和信令服务器来协调双方之间的通信,使Alice能够呼叫Eve并建立实时的音视频通信。

JSEP 支持 ICE Candidate Trickling,它允许呼叫者在初始报价后以增量方式向被呼叫者提供候选人,并允许被呼叫者开始对呼叫执行操作并建立连接,而无需等待所有候选人到达。

2.3 使用信令

看下代码,如下:

// handles JSON.stringify/parse
const signaling = new SignalingChannel();
const constraints = {audio: true, video: true};
const configuration = {iceServers: [{urls: 'stun:stun.example.org'}]};
const pc = new RTCPeerConnection(configuration);// Send any ice candidates to the other peer.
pc.onicecandidate = ({candidate}) => signaling.send({candidate});// Let the "negotiationneeded" event trigger offer generation.
pc.onnegotiationneeded = async () => {try {await pc.setLocalDescription(await pc.createOffer());// send the offer to the other peersignaling.send({desc: pc.localDescription});} catch (err) {console.error(err);}
};// After remote track media arrives, show it in remote video element.
pc.ontrack = (event) => {// Don't set srcObject again if it is already set.if (remoteView.srcObject) return;remoteView.srcObject = event.streams[0];
};// Call start() to initiate.
async function start() {try {// Get local stream, show it in self-view, and add it to be sent.const stream =await navigator.mediaDevices.getUserMedia(constraints);stream.getTracks().forEach((track) =>pc.addTrack(track, stream));selfView.srcObject = stream;} catch (err) {console.error(err);}
}signaling.onmessage = async ({desc, candidate}) => {try {if (desc) {// If you get an offer, you need to reply with an answer.if (desc.type === 'offer') {await pc.setRemoteDescription(desc);const stream =await navigator.mediaDevices.getUserMedia(constraints);stream.getTracks().forEach((track) =>pc.addTrack(track, stream));await pc.setLocalDescription(await pc.createAnswer());signaling.send({desc: pc.localDescription});} else if (desc.type === 'answer') {await pc.setRemoteDescription(desc);} else {console.log('Unsupported SDP type.');}} else if (candidate) {await pc.addIceCandidate(candidate);}} catch (err) {console.error(err);}
};

更多详细的代码,可以参看一个例子程序。

2.4 发现对方

这是一种奇特的提问方式,我如何找到可以交谈的人?

对于电话呼叫,您有电话号码和目录。对于在线视频聊天和消息传递,您需要身份和状态管理系统,以及用户启动会话的方法。WebRTC应用程序需要一种方法,让客户端相互发出信号,表明他们想要开始或加入通话。

对等发现机制不是由WebRTC定义的,该过程可以像通过电子邮件发送或消息传递 URL 一样简单。对于视频聊天应用(如对讲和浏览器会议),您可以通过共享自定义链接来邀请他人加入通话。

2.5 如何构建信令服务

重申一下,信令协议和机制不是由WebRTC标准定义的

无论您选择什么,都需要一个中间服务器在客户端之间交换信令消息和应用程序数据。可悲的是,网络应用程序不能简单地对互联网大喊:“将我连接到我的朋友!”

值得庆幸的是,信令消息很小,主要在通话开始时交换。在视频聊天会话的测试中,信令服务总共处理了大约 30-45 条消息,所有消息的总大小约为 10KB。

除了在带宽方面相对不要求外,WebRTC信令服务不会消耗太多的处理或内存,因为它们只需要中继消息并保留少量会话状态数据,例如连接了哪些客户端。

2.6 将消息从服务器推送到客户端

用于信令的消息服务必须是双向的:客户端到服务器和服务器到客户端。

双向通信违背了HTTP客户端/服务器请求/响应模型,但是多年来已经开发了各种技术黑客行为,例如长轮询,以便将数据从Web服务器上运行的服务推送到浏览器中运行的Web应用程序。

最近,EventSource API 已被广泛实现。这将启用服务器发送的事件 - 通过 HTTP 从 Web 服务器发送到浏览器客户端的数据。 专为单向消息传递而设计,但它可以与 XHR 结合使用,以构建用于交换信令消息的服务。信令服务通过向被叫方推送消息来传递来自呼叫方的消息,该消息由 XHR 请求传递。

WebSocket 是一种更自然的解决方案,专为全双工客户端-服务器通信而设计 - 可以同时在两个方向上流动的消息。使用纯 WebSocket 或服务器发送的事件, 构建的信令服务的一个优点是,这些 API 的后端可以在各种 Web 框架上实现,这些框架是大多数 Web 托管包(如 PHP、Python 和 Ruby)通用的。

当然,也可以通过让WebRTC客户端通过Ajax反复轮询消息传递服务器来处理信令,但这会导致大量冗余的网络请求,这对于移动设备来说尤其成问题。即使在建立会话后,对等方也需要轮询信令消息,以防其他对等方更改或会话终止。

2.7 现成的信令服务器

如果你不想自己动手,有几个WebRTC信令服务器可用,它们使用 Socket.IO ,并与WebRTC客户端JavaScript库集成:

  • webRTC.io 是WebRTC最早的抽象库之一。
  • Signalmaster是为与SimpleWebRTC JavaScript客户端库一起使用而创建的信令服务器。

如果你根本不想写任何代码,可以从vLine,OpenTok和Asterisk等公司获得完整的商业WebRTC平台。

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

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

相关文章

JS相关介绍

1.JS引入: 内部:直接在html文件内部使用script标签调用 外部:另外新建JS文件,再在html文件中调用 2.输入输出: 输入:prompt(请输入您的姓名:) 输出:document.write(你们真是天才) 注…

Nginx代理nginx.conf配置——反向代理(对WebSocket支持)

一、需求说明 基于Nginx代理nginx.conf配置——反向代理,如果要添加websocket支持,需要进行如下配置 二、配置内容 在http中添加一下配置,添加对websocket支持 http {# 配置其它内容map $http_upgrade $connection_upgrade {default upgra…

开心档之CSS 测验

目录 CSS 测验 CSS 测验 CSS测验是一种衡量前端开发人员对CSS的熟练程度的测试。通过CSS测验,可以评估一个人对CSS语言的掌握程度和应用能力,帮助公司或招聘方挑选合适的人才。下面将介绍如何进行CSS测验以及一些常见的CSS考题。 一、CSS测验的类型 1…

GaussDB WDR报告分析

标题 问题描述问题现象告警业务影响原因分析处理方法步骤 1步骤 2步骤 3步骤 4步骤 6步骤 7步骤 8步骤9步骤 10步骤 11步骤 12 问题描述 CPU使用率高。 问题现象 出现CPU使用率超过阈值,CPU使用率快速上涨或短时间持续较高水平等现象。 告警 CPU使用率告警。 …

Redis学习(二)线程安全、分布式锁、消息队列

文章目录 优惠券秒杀全局ID生成器优惠券秒杀下单超卖问题一人一单 分布式锁基于Redis的setnx指令实现分布式锁解决锁误删问题基于Lua脚本实现多条指令原子性Redis调用Lua脚本Java中使用Lua脚本 RedissonRedisson快速入门Redisson可重入锁原理Redisson的锁重试和Watchdog机制Red…

Unity物理相关组件——2D关节

一:前言 关节组件用来模拟物体与物体之间的连接关系,必须依赖于刚体组件 二:Hinge Joint 2D 用于实现链条物体、钟摆等物体的模拟 ——Enable Collision:是否开启碰撞 ——Connected Rigid Body:关联的刚体&#xff0…

JVM理论(三)运行时数据区--PC寄存器/虚拟机栈/本地方法栈

运行时数据区(JVM内存结构) JVM内存结构 内存是非常重要的资源,是硬盘和CPU的中间桥梁,承载操作系统和应用程序的实时运行.JVM内存布局规定java在运行过程中内存申请、分配、管理的策略,保证JVM高效稳定运行。不同的JVM对于内存划分和管理机制存在部分差异(如J9和JR…

[数据存储]HDFS的简介、初始化配置与运行

文章目录 HDFS简介HDFS数据存储访问方式HDFS节点HDFS的数据存储原理HDFS元数据(Block块管理)HDFS的数据读写流程HDFS数据写入流程HDFS数据读取流程 启动HDFSHDFS初始化配置${HADOOP_CONF_DIR}/hdfs-site.xml文件系统格式化启动HDFS查看启动状态 HDFS简介…

又是一条慢 SQL 改写,拿捏!

作者分享了一条慢 SQL 分析和优化的过程,总结出切实有效的优化手段。 作者:马文斌 MySQL 爱好者。 本文来源:原创投稿 爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。 背景 开发同学丢…

※Redis的事务、乐观锁和悲观锁

1.是神魔 在高并发的环境下,多个线程去竞争同一个资源, 比较常见的有高铁抢票系统,商品秒杀系统等,我们需要保证数据正确,同时系统的吞吐也要尽可能高。2.解决方案 1. 一般多线程同步我们就会想到加锁,用…

数据库作业——select查询操作

数据库作业 创建数据库 mysql> create table worker( -> 部门号 int(11) not null, -> 职工号 int(11) primary key not null,-> 工作时间 date not null,-> 工资…

MiniGPT4 在RTX-3090 Ubuntu服务器部署步骤详解

主要参考知乎帖子: MiniGPT-4 本地部署 RTX 3090 - 知乎 MiniGPT-4部署比麻烦,首先需要获取LLaMA权重,并结合Vicuna的bitwise XOR增量文件完成Vicuna模型权重生成,最后准备好预训练的MiniGPT-4进行模型部署。为了便于理解&#…