当前位置: 首页 > news >正文

Licode—基于webrtc的SFU/MCU实现

1. webrtc浅析


webrtc的前世今生、编译方法、行业应用、最佳实践等技术与产业类的文章在网上卷帙浩繁,重复的内容我不再赘述。对我来讲,webrtc的概念可以有三个角度去解释:

(1).一个W3C和IETF制定的标准,约定了Web间实时音视频通信机制,通过该标准可开发基于浏览器的、无插件的web多媒体应用(一般是js),该标准仅设定了点对点无中心的实时会话场景,没有强制约束信令协议与内容,没有要求有媒体处理的中心服务器,主要目标是形成开发者与浏览器厂商良好的生态环境,并积极向HTML5靠拢争取被纳入进去;

(2).一群音视频算法和网络适应性算法,这些算法囊括了视频会议几乎所有的核心技术,包括音视频的采集、编解码、网络传输、播放显示、安全等功能,还提供了操作系统系统调用跨平台封装的实现,包含Windows,Linux,Mac,Android,iOS;

(3).一个开源工程,核心由c++实现,可通过修改、封装、提取代码等方式实现一套视频会议系统,客户端可实现为Web js、App或Windows应用程序等多种形式,服务端可实现包括业务外的所有服务,包括媒体服务、信令服务、穿墙服务、中继服务等等,这些服务稍微调整后可轻易支持分布式部署、容器部署、云部署等。

对webrtc的理解与使用,我认为有三个境界:

(1).能搭建一个简易的视频会议系统,其中客户端部分可以这样做: Windows端Mac端Linux(x86)端在自带的peerconnection client或libjingle改一下(取决于信令是http还是sip家族信令);Android/iOS端在apprtc或licodeAndroidClient及Licode-ErizoClientIOS改一下;web端用webrtc 自带js api实现一下。服务端部分可以这样做:信令服务器在apprtc的collider改一下;穿墙服务器用自带的stun server,turn server部署一下;中继服务器在自带的relay server改一下;媒体服务器在kurentos、licode、jitsi、Intel Collaboration Suite for WebRTC或janus改一下;如果需要和传统的SIP体系互通则在webrtc2sip改一下;如果需要关注实时通信过程中的延时、丢包、接通率、掉线率等质量问题,可以部署callstats来进行专业监测;把所有服务都再部署于云平台的多个虚拟主机上或阿里云的容器云服务,完成以上操作就搭建起初级规模的云上视频会议系统原型了。

(2).能提取、理解并使用webrtc的算法模块,即或将算法模块融入到自己的代码中,或将自己的算法添加至webrtc里作为开源贡献或自己产品的差异性优势。值得提取的算法模块包括音视频编解码与处理框架(vp8、vp9、voice engine、video engine),音视频采集呈现封装、音视频预处理(NetEq、NS、AEC、Video Jitter Buffer)、网络适应性(GCC算法、ARQ、FEC)、安全性(Dtls、Srtp/Srtcp)等,自己可添加的有视频编码模块(x265、nvenc、intel qsv、xavs2、以及其他定制化的网络传输策略)。

(3).能够结合基于rtmp-cdn/p2p等直播技术,构建既支持交互互动,又支持海量围观,可商用、能运营、易扩展、全兼容的音视频PaaS服务平台,完成一个多媒体通信的终极产品。

Licode是达到第一境界技术层面所需要了解的开源工程,它从webrtc代码中提取出了SFU/MCU媒体服务所用到的音视频、媒体传输、信令的功能代码,结合libnice与libav实现了ICE与媒体转发功能,并封装成了可被调用的js API,此外还用js实现了包含全局管理服务、数据库服务、业务逻辑服务与信令媒体的调用服务的业务代码。Licode实现了webrtc开源工程没直接实现的中心侧的媒体服务功能,并提供了简单的业务模型与分布式部署方式,从而得到了多媒体通信工程师的广泛关注。但是Licode的相关文档与资料非常少,故本文是在我个人观察运行调试代码后总结所写的,不正确之处希望在留言中能够得以指正。

2. Licode系统分析


2.1 系统架构


Licode的系统架构如下,有客户端和服务端,客户端包括ErizoClient和NuveClient,分别用来进行信令与音视频交互和业务操作,类似于终端和会控集成在一起;服务端包括Nuve、ErizoController、ErizoAgent和MessageBus,分别用来实现业务服务与全局管理服务、信令服务、媒体服务和服务通信,其中ErizoController类似于MC、ErizoAgent类似于MP。

图1 系统架构图

2.2 客户端与服务端交互流程


客户端与服务端的交互流程如下图所示,其中客户端代码集中在N.API.js与Client.js上,服务端代码集中在nuve.js与erizoController.js上。

图2 信令交互图

3. 系统组成与模块划分


3.1 系统组成


本系统组成仅指服务端的系统组成,包括Nuve业务管理服务,ErizoController信令服务,ErizoAgent媒体服务,ErizoJS媒体转发实体。个人觉得代码在文件命名与文件组织结构上比较乱,初学者不易理解,如erizo_controller文件夹包括了除nuve以及webrtc的js api之外的所有js代码,不仅仅是erizoController,此外webrtc核心部分命名为erizo,也让人与整个系统相混淆。系统组成如下图所示,一个Nuve管理多个ErizoController(以下简称EC),一个EC管理多个ErizoAgent(以下简称EA),一个EA管理多个ErizoJS(以下简称EJ),一个EJ就是一个SFU,封装了C++实现的webrtc、libav与libnice。

图3 服务端系统组成图

3.2 Nuve业务管理服务


图4 Nuve业务管理服务

图5 Nuve各模块用途及对应文件

此外,这篇文章Licode(二):Nuve源码分析 - CSDN博客 对Nuve做了更详细的分析。

3.3 ErizoController信令服务


图6 ErizoController信令服务

图7 ErizoController各模块用途及对应文件

3.4 ErizoAgent媒体服务


图8 ErizoAgent媒体服务

图9 ErizoAgent各模块用途及对应文件

3.5 ErizoJS媒体转发实体


图10 ErizoJS媒体转发实体

图11 ErizoJS各模块用途及对应文件

3.6 webrtc


由于webrtc工程代码本身非常庞大,编译工具也很独特,Licode并未全部引入,仅仅抽取了webrtc的部分代码,如下图所示

图12 webrtc各组件用途及对应目录

由此可见,所抽取的代码没有webrtc自带的音视频处理框架(voice engine/video engine/media engine),这是由于SFC只在RTP层进行转发并不解码,只需要check一下媒体流属性(如I帧头)即可。抽取代码的亮点在于将webrtc强大的抵抗网络时延和丢包的网络适应性算法和协议都提炼出来了,可以供广大研究视频传输的网络适应方向的开发者们单独学习、实验并快速集成到自己非webrtc-based的产品中来。

webrtc的网络适应性手段包括丢包重传(ARQ)、前向纠错(FEC)和拥塞控制(GCC),其中自动码率(ARC)在GCC中。对网络适应性有兴趣的朋友可对照代码看如下几篇博文:

(1). 丢包重传 (ARQ)

RFC4585 RTP/AVPF 传输层反馈;

RFC4588 4585补充 重传包格式;

RFC5104 4585补充 负载层反馈;

RFC5124 RTP/SAVPF

RFC5450 4585补充 Jitter报告

(2). 前向纠错 (FEC)

RFC2198 WebRTC中的前向纠错编码 - Red Packet

RFC5109 WebRTC 的前向纠错编码 - XOR FEC

(3). 带宽检测 (BWE)

传统的基于RTCP RR报文中丢包数来进行带宽检测的算法目前被认为是最low的了,因为属于事后处理;先进的算法是需要事前感知的(突发情况除外),假定带宽是逐渐变窄的,根据信号估计理论可以在网络链路发生丢包以前就监测到网络拥塞,

GCC草案

REMB草案

GCC算法与函数调用 WebRTC基于GCC的拥塞控制(上) - 算法分析 WebRTC基于GCC的拥塞控制(下) - 实现分析

带宽估计 WebRTC之带宽控制部分学习(1) ------基本demo的介绍

带宽检测 WebRTC 中的带宽侦测 - CSDN博客

接收缓冲区延迟估计 WebRTC视频接收缓冲区基于KalmanFilter的延迟模型

3.7 libav、libnice、libsrtp


libav是从ffmpeg分离出的开发者发布的开源工程,与早期ffmpeg有很大相似性,对于仅调用api的开发者来说就简单看成是代码量更小、第三方依赖库更少、编译更简单的轻量级ffmpeg吧。这个库在Licode编译过程中有处问题,Licode使用版本较旧的libav的接口,其中avcodec_alloc_frame和avcodec_free_frame都已经遗弃,改为av_frame_alloc/av_frame_free才可编译通过。

libnice库基于ICE协议实现的网络层库,Licode使用libnice库来实现端到端的ICE连接和数据流发送接收,以及candidates(候选地址)和SDP(媒体描述文件)的相互交换。

libsrtp库主要是是用来加密rtp/rtcp的。

4. 关键技术


4.1 网络收发流水线架构技术


网络收发或一个SFU实现,并非简单的从一个源地址收到若干个数据包再复制多份发送给多个目的地址,正如3.6所描述,除了需要堆栈式的ICE地址转换、DTLS/SRTP的解密,还需要流水线式的RTP/RTCP的丢包检测与重传、FEC处理、带宽检测与估计、包缓冲区调整以及平滑发送等若干个复杂步骤,这个流程在Licode代码中是通过Pipeline-Handler这样的架构实现的,由于webrtc仅提供底层算法并未提供SFU架构,所以我认为这种架构是Licode最重要的关键技术,可供未来想成为软件架构师的开发者参考学习。日后我也再详细分析这个架构,看看是否能抽象出一个新的设计模式来。

整个网络收发的层级模型图如下图所示,其中每一层右侧标注出了关键类。

图13 网络收发层级模型

Pipeline的类图如下图

图14 Pipeline相关类图

对Pipeline来说,需要全局管理、长时处理或非逐个包处理的流程,实现对象叫Service,包括Handler的管理、RTCP的计算与处理、当前状态的处理、网络质量的管理以及包缓冲的管理都是Service;而需要每次逐包处理的流程,实现对象叫Handler,包括19项Handler,其代码都位于erizo\src\erizo\rtp目录下

//新增全局处理的Service

pipeline_->addService(handler_manager_);

pipeline_->addService(rtcp_processor_);

pipeline_->addService(stats_);

pipeline_->addService(quality_manager_);

pipeline_->addService(packet_buffer_);

//新增单次处理的Handler

pipeline_->addFront(std::make_shared<RtcpProcessorHandler>());

pipeline_->addFront(std::make_shared<FecReceiverHandler>());

pipeline_->addFront(std::make_shared<LayerBitrateCalculationHandler>());

pipeline_->addFront(std::make_shared<QualityFilterHandler>());

pipeline_->addFront(std::make_shared<IncomingStatsHandler>());

pipeline_->addFront(std::make_shared<RtpTrackMuteHandler>());

pipeline_->addFront(std::make_shared<RtpSlideShowHandler>());

pipeline_->addFront(std::make_shared<RtpPaddingGeneratorHandler>());

pipeline_->addFront(std::make_shared<PliPacerHandler>());

pipeline_->addFront(std::make_shared<BandwidthEstimationHandler>());

pipeline_->addFront(std::make_shared<RtpPaddingRemovalHandler>());

pipeline_->addFront(std::make_shared<RtcpFeedbackGenerationHandler>());

pipeline_->addFront(std::make_shared<RtpRetransmissionHandler>());

pipeline_->addFront(std::make_shared<SRPacketHandler>());

pipeline_->addFront(std::make_shared<SenderBandwidthEstimationHandler>());

pipeline_->addFront(std::make_shared<LayerDetectorHandler>());

pipeline_->addFront(std::make_shared<OutgoingStatsHandler>());

pipeline_->addFront(std::make_shared<PacketCodecParser>());

pipeline_->addFront(std::make_shared<PacketWriter>(this));

4.2 分布式保活技术


Licode的系统设计如3.1所述,Nuve管理多个EC,EC管理多个EA,EA启动多个EJ进程;在资源上,Nuve负责EC的负载均摊,EC负责EA和EJ的负载均摊(毕竟EJ在EA内,EA除了监控OS性能并未太多其他工作),故Nuve需要EC分布式保活,EC需要EA分布式保活。Licode实现比较简单,代码可参考CloudHandler.js与ecCloudHandler.js。

例如Nuve每启动一个EC立刻分配id,并加入到ECList中,并在DB中写入id作为key,且在该key对应的value上进行累加,此后Nuve的秒级循环中不断check这个value并继续累加,如果超过阈值,则认为该EC失效,将此EC从list中删除。Nuve同时提供keepalive接口,EC通过RPC调用此接口不断对数据库中本id的value清零,从而实现了分布式保活。EC与EA间方法一样。

4.3 资源管理技术


这里定义的资源有三个含义:设备资源(设备简单分为发布设备、接收设备、收发设备)、内容资源(某地的实时视频或已录制视频)以及server处理能力余量(例如还能转发的路数,还能容纳的新成员)。

Licode的publish-subscribe模型将信令交互、内容管理(源站管理)、媒体分发三者分开,从而可实现多维度的资源管理。

Client 1 发的第一个信令仅起到了一个资源注册的作用,即room中存在Client 1的id了;

Client 1 发的第二个信令表明该id可以发布新内容了,内容为Stream 1;

Client 2 同理,room记录了Client 2的id与Stream 2;

Client 1发的第三个信令表明对Client 2的Stream 2内容感兴趣开始订阅了,于是启动了SFU过程;

Client 3加入room后,可以发布资源(Stream3),可以订阅资源(Stream1、Stream2),也可以什么都不做,因为任何在该room中注册的设备都可以pubilsh内容资源或subscirbe已publish的内容资源。完全解耦带来的好处是内容资源同设备资源一样也可以轻易管理了,在启动SFU过程中,server处理能力余量也能得到较好的管理。

H.323是紧耦合的,信令交互后必须开启媒体交互(电路交换的思维,信道容量有限,申请资源赶紧用,用完赶紧释放),对内容管理过于依赖于会议逻辑的实现,为了实现更灵活的互听互看,其逻辑会堆砌的很复杂。

然而好的方法也不是万能的,publish-subscribe的完全解耦虽带来极大的可扩展性,但对于某些传统业务更复杂了。比如MCU两个终端互看,就需要启动两个erizoJS,互相订阅发布,根据负载均摊的算法,可能两个erizoJS都不在一个erizoAgent里(不在同一台物理机或虚拟机上)。MCU轮询模式也稍复杂,轮询者需要不断的subscribe room中的发布者,发布者也要不断的去remove、add,切换速度比接收所有流+I Frame Check的传统方式要慢的多。

5. 总结


本文先介绍了自己对webrtc的概念理解与使用参考,接下来从系统架构、交互流程、系统组成与模块划分几个角度对Licode进行概要设计级别的分析,最后对自己觉得Licode比较有特色的三大技术,即网络收发流水线架构技术、分布式保活技术与资源管理技术进行了浅层次的解释。文中表述内容可能会有不准确之处,希望能与读者们交流并及时改正。

原文https://zhuanlan.zhihu.com/p/40462946

★文末名片可以免费领取音视频开发学习资料,内容包括(FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs)以及音视频学习路线图等等。

见下方!↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

相关文章:

Licode—基于webrtc的SFU/MCU实现

1. webrtc浅析webrtc的前世今生、编译方法、行业应用、最佳实践等技术与产业类的文章在网上卷帙浩繁&#xff0c;重复的内容我不再赘述。对我来讲&#xff0c;webrtc的概念可以有三个角度去解释&#xff1a;&#xff08;1&#xff09;.一个W3C和IETF制定的标准&#xff0c;约定…...

开发运维工具推荐 --- 解决远程访问局域网服务的问题。开发调试推荐

一、FastNat 可为您解决的问题1. 没公网服务器&#xff0c;需要发布本地的站点或网络程序到公网上&#xff0c;供他人访问&#xff1b;此项功能大大方面开发人员进行远程调试&#xff0c;微信小程序等开发工作进行。2. 需要远程到在其他网络中的设备&#xff0c;但两处的网络不…...

【华为OD机试 】单词倒序(C++ Java JS Python)

文章目录 题目描述输入描述输出描述备注用例题目解析C++ 解法JavaScript算法源码Java算法源码Python解法题目描述 输入单行英文句子,里面包含英文字母,空格以及,.?三种标点符号,请将句子内每个单词进行倒序,并输出倒序后的语句。 输入描述 输入字符串S,S的长度 1 ≤ N…...

PLC 诊断故障的基本原理

(1)东欢坨选煤厂机电设备故障信号主要取自开关量信号,PLC 通过开关量的通和断对设备进行故障诊断。PLC 对开关量的识别是通过输入模块来实现的。PLC 控制设备运行时,设备中的温度、压力、急停、跑偏、速度、过热以及各种按钮和行程开关的传感器与 PLC 输入模块相连接,输入模块的…...

QT打开外部程序并嵌入Qt子窗口的缺点

首先可以参考如下文章&#xff1a; QT打开外部程序并嵌入Qt界面_qt界面嵌入外部应用程序_初学小白Lu的博客-CSDN博客 Qt嵌入外部程序界面初探_qt嵌入其他程序窗口_liming4675的博客-CSDN博客 QT 如何把外部程序嵌入到QT界面_qt嵌入其他程序窗口_hellokandy的博客-CSDN博客 Qt界…...

如何系统地学习 C++ 语言?

C作为具有广泛适用性的编程语言&#xff0c;学习C的人越来越多&#xff0c;但是如何系统地学习C还是个问题&#xff0c;下面我们一起来看一下C学习的方法有哪些吧。 首先&#xff0c;要学习C&#xff0c;最重要的就是掌握C的基础知识。 比如数据结构、算法、微积分等。这些都是…...

【数据结构】单链表

链表1.为什么存在链表2.链表的概念3.单链表的实现4.测试1.为什么存在链表 我们在学习顺序表的时候&#xff0c;了解到顺序表有一定的缺陷&#xff1a;&#xff08;1&#xff09;在中间插入数据和删除数据需要挪动数据&#xff0c;时间复杂度是O&#xff08;N&#xff09;&…...

Windows 右键菜单扩展容器 [开源]

今天给大家分享一个我做的小工具&#xff0c;可以自定义扩展右键菜单的功能来提高工作效率&#xff0c;效果图如下&#xff1a; 如上图&#xff0c;右键菜单多了几个我自定义的菜单&#xff1a; 复制文件路径 复制文件夹路径 我的工具箱 <走配置文件动态创建子菜单&#x…...

爆文制造机!小红书热榜3个方向,告诉你选题诀窍!

我们知道&#xff0c;不论是达人创作内容&#xff0c;还是品牌制定Brief&#xff0c;都需要提前调研筛选海量信息&#xff0c;这时候如果有一个自己的内容素材库&#xff0c;就省事多啦。按照内容需求&#xff0c;我们可以按3个角度划分小红书内容素材&#xff1a;笔记类型、竞…...

【Web安全社工篇】——水坑攻击

作者名&#xff1a;白昼安全主页面链接&#xff1a; 主页传送门创作初心&#xff1a; 以后赚大钱座右铭&#xff1a; 不要让时代的悲哀成为你的悲哀专研方向&#xff1a; web安全&#xff0c;后渗透技术每日鸡汤&#xff1a;努力赚钱不是因为爱钱“水坑攻击”&#xff0c;黑客攻…...

SpringBoot 整合 MongoDB 实现数据的增删改查!

一、介绍在 MongoDB 中有三个比较重要的名词&#xff1a;数据库、集合、文档&#xff01;数据库&#xff08;Database&#xff09;&#xff1a;和关系型数据库一样&#xff0c;每个数据库中有自己的用户权限&#xff0c;不同的项目组可以使用不同的数据库集合&#xff08;Colle…...

VUE前端常问面试题

文章目录一、VUE前端常问面试题二、文档下载地址一、VUE前端常问面试题 1、MVC和MVVM 区别 MVC&#xff1a;MVC全名是 Model View Controller&#xff0c;即模型-视图-控制器的缩写&#xff0c;一种软件设计典范。 Model(模型)&#xff1a;是用于处理应用程序数据逻辑部分。通…...

c++中map/unordered_map的不同遍历方式以及结构化绑定

文章目录方式一&#xff1a;值传递遍历方式二&#xff1a;引用传递遍历方式三&#xff1a;使用迭代器遍历方式四&#xff1a;结构化绑定(c17特性)结构化绑定示例&#xff08;1&#xff09;元组tuple结构化绑定&#xff08;2&#xff09;结构体结构化绑定&#xff08;3&#xff…...

Kafka系列之:Kraft模式

Kafka系列之:Kraft模式 一、Kraft架构二、Kafka的Kraft集群部署三、初始化集群数据目录四、创建KafkaTopic五、查看Kafka Topic六、创建生产者七、创建消费者一、Kraft架构 Kafka元数据存储在zookeeper中,运行时动态选举controller,由controller进行Kafka集群管理。Kraft模式…...

动态规划:leetcode 139.单词拆分、多重背包问题

leetcode 139.单词拆分leetcode 139.单词拆分给定一个非空字符串 s 和一个包含非空单词的列表 wordDict&#xff0c;判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。说明&#xff1a;拆分时可以重复使用字典中的单词。你可以假设字典中没有重复的单词。示例 1&…...

Stable Diffusion原理详解

Stable Diffusion原理详解 最近AI图像生成异常火爆&#xff0c;听说鹅厂都开始用AI图像生成做前期设定了&#xff0c;小厂更是直接用AI替代了原画师的岗位。这一张张丰富细腻、风格各异、以假乱真的AI生成图像&#xff0c;背后离不开Stable Diffusion算法。 Stable Diffusion…...

webpack高级配置

摇树&#xff08;tree shaking&#xff09; 我主要是想说摇树失败的原因&#xff08;tree shaking 失败的原因&#xff09;&#xff0c;先讲下摇树本身效果 什么是摇树&#xff1f; 举个例子 首先 webpack.config.js配置 const webpack require("webpack");/**…...

jQuery 事件

jQuery 事件 Date: February 28, 2023 Sum: jQuery事件注册、处理、对象 目标&#xff1a; 能够说出4种常见的注册事件 能够说出 on 绑定事件的优势 能够说出 jQuery 事件委派的优点以及方式 能够说出绑定事件与解绑事件 jQuery 事件注册 单个时间注册 语法&#xff1a;…...

【批处理脚本】-2.3-解析地址命令arp

"><--点击返回「批处理BAT从入门到精通」总目录--> 共2页精讲(列举了所有arp的用法,图文并茂,通俗易懂) 目录 1 arp命令解析 1.1 询问当前协议数据,显示当前 ARP 项...

改进 YOLO V5 的密集行人检测算法研究(论文研读)——目标检测

改进 YOLO V5 的密集行人检测算法研究&#xff08;2021.08&#xff09;摘 要&#xff1a;1 YOLO V52 SENet 通道注意力机制3 改进的 YOLO V5 模型3.1 训练数据处理改进3.2 YOLO V5 网络改进3.3 损失函数改进3.3.1 使用 CIoU3.3.2 非极大值抑制改进4 研究方案与结果分析4.1 实验…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

C++.OpenGL (10/64)基础光照(Basic Lighting)

基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

Mobile ALOHA全身模仿学习

一、题目 Mobile ALOHA&#xff1a;通过低成本全身远程操作学习双手移动操作 传统模仿学习&#xff08;Imitation Learning&#xff09;缺点&#xff1a;聚焦与桌面操作&#xff0c;缺乏通用任务所需的移动性和灵活性 本论文优点&#xff1a;&#xff08;1&#xff09;在ALOHA…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍&#xff1a; img 属性指定分区存放的 image 名称&#xff0c;指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件&#xff0c;则以 proj_name:binary_name 格式指定文件名&#xff0c; proj_name 为工程 名&…...

解读《网络安全法》最新修订,把握网络安全新趋势

《网络安全法》自2017年施行以来&#xff0c;在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂&#xff0c;网络攻击、数据泄露等事件频发&#xff0c;现行法律已难以完全适应新的风险挑战。 2025年3月28日&#xff0c;国家网信办会同相关部门起草了《网络安全…...

适应性Java用于现代 API:REST、GraphQL 和事件驱动

在快速发展的软件开发领域&#xff0c;REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名&#xff0c;不断适应这些现代范式的需求。随着不断发展的生态系统&#xff0c;Java 在现代 API 方…...

Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案

在大数据时代&#xff0c;海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构&#xff0c;在处理大规模数据抓取任务时展现出强大的能力。然而&#xff0c;随着业务规模的不断扩大和数据抓取需求的日益复杂&#xff0c;传统…...

消息队列系统设计与实践全解析

文章目录 &#x1f680; 消息队列系统设计与实践全解析&#x1f50d; 一、消息队列选型1.1 业务场景匹配矩阵1.2 吞吐量/延迟/可靠性权衡&#x1f4a1; 权衡决策框架 1.3 运维复杂度评估&#x1f527; 运维成本降低策略 &#x1f3d7;️ 二、典型架构设计2.1 分布式事务最终一致…...