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

JavaScript系列(38)-- WebRTC技术详解

JavaScript WebRTC技术详解 🎥

今天,让我们深入了解WebRTC(Web Real-Time Communication)技术,这是一种支持网页浏览器进行实时语音对话或视频对话的技术。

WebRTC基础概念 🌟

💡 小知识:WebRTC是一个开源项目,旨在使得浏览器能够进行实时音视频通信,而无需安装任何插件。它不仅支持音视频传输,还支持任意数据的点对点传输。

基本实现 📊

// 1. WebRTC连接管理器
class RTCConnectionManager {constructor(configuration = {}) {this.configuration = {iceServers: [{ urls: 'stun:stun.l.google.com:19302' }],...configuration};this.peerConnection = null;this.dataChannel = null;}async initialize() {try {this.peerConnection = new RTCPeerConnection(this.configuration);this.setupEventListeners();return this.peerConnection;} catch (error) {console.error('Failed to create peer connection:', error);throw error;}}setupEventListeners() {this.peerConnection.onicecandidate = event => {if (event.candidate) {// 发送ICE候选者到远程对等端this.onIceCandidate(event.candidate);}};this.peerConnection.onconnectionstatechange = () => {console.log('Connection state:',this.peerConnection.connectionState);};this.peerConnection.oniceconnectionstatechange = () => {console.log('ICE connection state:',this.peerConnection.iceConnectionState);};}async createOffer() {try {const offer = await this.peerConnection.createOffer();await this.peerConnection.setLocalDescription(offer);return offer;} catch (error) {console.error('Failed to create offer:', error);throw error;}}async handleAnswer(answer) {try {await this.peerConnection.setRemoteDescription(new RTCSessionDescription(answer));} catch (error) {console.error('Failed to handle answer:', error);throw error;}}async handleIceCandidate(candidate) {try {await this.peerConnection.addIceCandidate(new RTCIceCandidate(candidate));} catch (error) {console.error('Failed to add ICE candidate:', error);throw error;}}
}// 2. 媒体流管理器
class MediaStreamManager {constructor() {this.localStream = null;this.remoteStream = null;}async getLocalStream(constraints = {audio: true,video: true}) {try {this.localStream = await navigator.mediaDevices.getUserMedia(constraints);return this.localStream;} catch (error) {console.error('Failed to get local stream:', error);throw error;}}async getDisplayMedia(constraints = {video: {cursor: "always"},audio: false}) {try {return await navigator.mediaDevices.getDisplayMedia(constraints);} catch (error) {console.error('Failed to get display media:', error);throw error;}}attachStreamToElement(stream, element) {element.srcObject = stream;element.onloadedmetadata = () => {element.play().catch(error => {console.error('Failed to play stream:', error);});};}stopLocalStream() {if (this.localStream) {this.localStream.getTracks().forEach(track => track.stop());this.localStream = null;}}
}// 3. 数据通道管理器
class DataChannelManager {constructor(peerConnection) {this.peerConnection = peerConnection;this.dataChannel = null;}createDataChannel(label = 'dataChannel', options = {}) {this.dataChannel = this.peerConnection.createDataChannel(label,options);this.setupDataChannelEvents();return this.dataChannel;}setupDataChannelEvents() {this.dataChannel.onopen = () => {console.log('Data channel is open');};this.dataChannel.onclose = () => {console.log('Data channel is closed');};this.dataChannel.onmessage = event => {console.log('Received message:', event.data);};this.dataChannel.onerror = error => {console.error('Data channel error:', error);};}sendMessage(message) {if (this.dataChannel && this.dataChannel.readyState === 'open') {this.dataChannel.send(message);} else {throw new Error('Data channel is not open');}}
}

高级功能实现 🚀

// 1. 音视频处理器
class MediaProcessor {constructor(stream) {this.stream = stream;this.audioContext = new AudioContext();}async applyAudioEffects() {const source = this.audioContext.createMediaStreamSource(this.stream);const gainNode = this.audioContext.createGain();const analyser = this.audioContext.createAnalyser();source.connect(gainNode);gainNode.connect(analyser);analyser.connect(this.audioContext.destination);return {setVolume: (value) => {gainNode.gain.value = value;},getAudioData: () => {const data = new Uint8Array(analyser.frequencyBinCount);analyser.getByteFrequencyData(data);return data;}};}async applyVideoFilters(videoElement) {const canvas = document.createElement('canvas');const ctx = canvas.getContext('2d');const processFrame = () => {ctx.drawImage(videoElement, 0, 0);const imageData = ctx.getImageData(0, 0,canvas.width,canvas.height);// 应用滤镜效果this.applyFilter(imageData.data);ctx.putImageData(imageData, 0, 0);requestAnimationFrame(processFrame);};processFrame();return canvas.captureStream();}applyFilter(pixels) {for (let i = 0; i < pixels.length; i += 4) {// 简单的灰度滤镜const avg = (pixels[i] + pixels[i + 1] + pixels[i + 2]) / 3;pixels[i] = avg;     // Rpixels[i + 1] = avg; // Gpixels[i + 2] = avg; // B}}
}// 2. 网络质量监控器
class NetworkMonitor {constructor(peerConnection) {this.peerConnection = peerConnection;this.stats = {bytesReceived: 0,bytesSent: 0,packetsLost: 0,roundTripTime: 0};}async startMonitoring(interval = 1000) {setInterval(async () => {const stats = await this.peerConnection.getStats();stats.forEach(report => {if (report.type === 'inbound-rtp') {this.stats.bytesReceived = report.bytesReceived;this.stats.packetsLost = report.packetsLost;} else if (report.type === 'outbound-rtp') {this.stats.bytesSent = report.bytesSent;} else if (report.type === 'candidate-pair' && report.state === 'succeeded') {this.stats.roundTripTime = report.currentRoundTripTime;}});this.onStatsUpdate(this.stats);}, interval);}onStatsUpdate(stats) {console.log('Network stats:', stats);// 可以在这里实现自定义的统计数据处理逻辑}getConnectionQuality() {const rtt = this.stats.roundTripTime;if (rtt < 0.1) return 'Excellent';if (rtt < 0.3) return 'Good';if (rtt < 0.5) return 'Fair';return 'Poor';}
}// 3. 信令服务器连接器
class SignalingConnector {constructor(url) {this.url = url;this.socket = null;this.handlers = new Map();}connect() {this.socket = new WebSocket(this.url);this.socket.onopen = () => {console.log('Connected to signaling server');};this.socket.onmessage = event => {const message = JSON.parse(event.data);const handler = this.handlers.get(message.type);if (handler) {handler(message.data);}};this.socket.onerror = error => {console.error('Signaling server error:', error);};this.socket.onclose = () => {console.log('Disconnected from signaling server');// 实现重连逻辑setTimeout(() => this.connect(), 5000);};}send(type, data) {if (this.socket && this.socket.readyState === WebSocket.OPEN) {this.socket.send(JSON.stringify({ type, data }));}}on(type, handler) {this.handlers.set(type, handler);}
}

性能优化技巧 ⚡

// 1. 媒体流优化器
class StreamOptimizer {constructor() {this.encodingParams = {maxBitrate: 1000000,maxFramerate: 30,scaleResolutionDownBy: 1};}async optimizeVideoStream(stream, constraints) {const videoTrack = stream.getVideoTracks()[0];if (!videoTrack) return stream;const sender = this.peerConnection.getSenders().find(s => s.track.kind === 'video');if (sender) {const params = sender.getParameters();params.encodings = [this.encodingParams];await sender.setParameters(params);}return stream;}async adaptToNetworkConditions(stats) {if (stats.roundTripTime > 0.3) {// 降低视频质量this.encodingParams.maxBitrate = 500000;this.encodingParams.maxFramerate = 15;this.encodingParams.scaleResolutionDownBy = 2;} else {// 恢复视频质量this.encodingParams.maxBitrate = 1000000;this.encodingParams.maxFramerate = 30;this.encodingParams.scaleResolutionDownBy = 1;}}
}// 2. 连接优化器
class ConnectionOptimizer {constructor(peerConnection) {this.peerConnection = peerConnection;this.retryAttempts = 0;this.maxRetries = 3;}async optimizeIceServers() {const servers = await this.fetchIceServers();this.peerConnection.setConfiguration({iceServers: servers});}async handleConnectionFailure() {if (this.retryAttempts >= this.maxRetries) {throw new Error('Connection failed after max retries');}this.retryAttempts++;await this.optimizeIceServers();await this.peerConnection.restartIce();}async fetchIceServers() {// 实现动态获取TURN服务器列表的逻辑return [{ urls: 'stun:stun.l.google.com:19302' },// 添加其他TURN服务器];}
}// 3. 资源管理器
class ResourceManager {constructor() {this.resources = new Map();}async allocateResources(constraints) {const stream = await navigator.mediaDevices.getUserMedia(constraints);this.resources.set('stream', stream);return stream;}releaseResources() {for (const [key, resource] of this.resources) {if (resource instanceof MediaStream) {resource.getTracks().forEach(track => track.stop());}}this.resources.clear();}monitorResourceUsage() {setInterval(() => {const usage = {cpu: performance.now(),memory: window.performance.memory?.usedJSHeapSize};console.log('Resource usage:', usage);}, 5000);}
}

最佳实践建议 💡

  1. 错误处理和恢复
// 1. 错误处理器
class WebRTCErrorHandler {static handle(error, context) {console.error(`Error in ${context}:`, error);if (error.name === 'NotAllowedError') {return this.handlePermissionError();}if (error.name === 'NotFoundError') {return this.handleDeviceError();}if (error.name === 'NotReadableError') {return this.handleHardwareError();}return this.handleGenericError(error);}static handlePermissionError() {return {type: 'permission',message: 'Please allow camera and microphone access'};}static handleDeviceError() {return {type: 'device',message: 'No camera or microphone found'};}static handleHardwareError() {return {type: 'hardware',message: 'Hardware error occurred'};}static handleGenericError(error) {return {type: 'generic',message: error.message};}
}// 2. 连接恢复策略
class ConnectionRecoveryStrategy {constructor(rtcManager) {this.rtcManager = rtcManager;this.retryCount = 0;this.maxRetries = 3;this.retryDelay = 1000;}async attemptRecovery() {if (this.retryCount >= this.maxRetries) {throw new Error('Max retry attempts reached');}await new Promise(resolve => setTimeout(resolve, this.retryDelay * Math.pow(2, this.retryCount)));this.retryCount++;return this.rtcManager.initialize();}reset() {this.retryCount = 0;}
}// 3. 安全策略
class SecurityPolicy {constructor() {this.allowedOrigins = new Set();this.encryptionEnabled = true;}validatePeer(peerId) {// 实现对等端验证逻辑return true;}encryptData(data) {if (!this.encryptionEnabled) return data;// 实现数据加密逻辑return data;}decryptData(data) {if (!this.encryptionEnabled) return data;// 实现数据解密逻辑return data;}
}

结语 📝

WebRTC技术为Web应用提供了强大的实时通信能力。通过本文,我们学习了:

  1. WebRTC的基本概念和实现
  2. 音视频流的处理和优化
  3. 网络质量监控和适配
  4. 性能优化技巧
  5. 错误处理和安全考虑

💡 学习建议:在使用WebRTC时,要特别注意网络条件的适配和错误处理。同时,要考虑浏览器兼容性和降级处理,确保在各种环境下都能提供良好的用户体验。


如果你觉得这篇文章有帮助,欢迎点赞收藏,也期待在评论区看到你的想法和建议!👇

终身学习,共同成长。

咱们下一期见

💻

相关文章:

JavaScript系列(38)-- WebRTC技术详解

JavaScript WebRTC技术详解 &#x1f3a5; 今天&#xff0c;让我们深入了解WebRTC&#xff08;Web Real-Time Communication&#xff09;技术&#xff0c;这是一种支持网页浏览器进行实时语音对话或视频对话的技术。 WebRTC基础概念 &#x1f31f; &#x1f4a1; 小知识&…...

分布式理解

分布式 如何理解分布式 狭义的分布是指&#xff0c;指多台PC在地理位置上分布在不同的地方。 分布式系统 分布式系**统&#xff1a;**多个能独立运行的计算机&#xff08;称为结点&#xff09;组成。各个结点利用计算机网络进行信息传递&#xff0c;从而实现共同的“目标或者任…...

JVM学习指南(48)-JVM即时编译

文章目录 即时编译(Just-In-Time Compilation, JIT)概述为什么JVM需要即时编译?即时编译与传统的静态编译的区别JVM中的即时编译器HotSpot VM中的C1和C2编译器编译器的作用和位置即时编译的工作流程代码的加载和解释执行热点代码检测编译优化编译优化技术公共子表达式消除循…...

python http调用视觉模型moondream

目录 一、什么是moondream 二、资源地址 三、封装了http进行接口请求 四、代码解析 解释 可能的改进 一、什么是moondream Moondream 是一个针对视觉生成任务的深度学习模型,专注于图像理解和生成,包括图像标注(captioning)、问题回答(Visual Question Answering,…...

【竞技宝】DOTA2:NAVI junior被ESL取消参赛资格

北京时间1月24日,DOTA2目前有多个赛事的预选赛正在如火如荼的进行之中,其中ESLOne罗利站的预选赛已经结束,参赛正赛的队伍也已经全部产生。除了因EPT积分而拿到直邀资格的PARI、BB、falcons、liquid之外,tundra、NAVI junior、spirit、nigma、XG、talon、SR、HEROIC也通过各赛区…...

Java 在包管理与模块化中的优势:与其他开发语言的比较

在开发复杂的、规模庞大的软件系统时&#xff0c;包管理和模块化设计起着至关重要的作用。它们不仅决定了代码的组织和可维护性&#xff0c;还直接影响到团队协作效率、扩展性和性能。在众多编程语言中&#xff0c;Java 凭借其成熟的生态系统、强类型系统和标准化的包管理机制&…...

如何用数据编织、数据虚拟化与SQL-on-Hadoop打造实时、可扩展兼容的数据仓库?

在大数据技术迅猛发展的背景下&#xff0c;许多人认为传统数据仓库已过时。然而&#xff0c;这种观点忽略了数据仓库的核心价值&#xff1a;统一的数据视图、强大的业务逻辑支撑以及丰富的数据分析能力。在企业数据架构转型中&#xff0c;数据仓库不仅未被淘汰&#xff0c;反而…...

MVCC底层原理实现

MVCC的实现原理 了解实现原理之前&#xff0c;先理解下面几个组件的内容 1、 当前读和快照读 先普及一下什么是当前读和快照读。 当前读&#xff1a;读取数据的最新版本&#xff0c;并对数据进行加锁。 例如&#xff1a;insert、update、delete、select for update、 sele…...

【Nacos】负载均衡

目录 前言 一、服务下线二、权重配置三、同一个集群优先访问四、环境隔离 前言 我们的生产环境相对是比较恶劣的&#xff0c;我们需要对服务的流量进行更加精细的控制.Nacos支持多种负载均衡策略&#xff0c;包括配置权重&#xff0c;同机房&#xff0c;同地域&#xff0c;同环…...

Batch Normalization学习笔记

文章目录 一、为何引入 Batch Normalization二、具体步骤1、训练阶段2、预测阶段 三、关键代码实现四、补充五、参考文献 一、为何引入 Batch Normalization 现在主流的卷积神经网络几乎都使用了批量归一化&#xff08;Batch Normalization&#xff0c;BN&#xff09;1&#xf…...

PIC单片机HEX文件格式分析

在调试PIC单片机在bootloader程序时&#xff0c;需要将hex文件转换为bin文件&#xff0c;在转换之前先了解一下hex文件中数据是如何定义的。 直接打开一个LED灯闪烁的程序生成的hex文件&#xff0c;芯片型号为PIC18F46K80 可以看到每条数据都是由6部分组成的&#xff0c;下面分…...

【unity游戏开发之InputSystem——07】InputSystem+UGUI配合使用(基于unity6开发介绍)

文章目录 一、InputSystem+UGUI配合使用1、官方文档参考2、切换到新的输入模块二、UGUI中的新输入系统输入模块参数相关1、Send Pointer Hover To Parent2、Move Repeat Delay3、Move Repeat Rate4、XR Tracking Origin5、Deselect On Background CLick6、Pointer Behavior7、S…...

RocketMQ 的 Topic 和消息队列MessageQueue信息,是怎么分布到Broker的?怎么负载均衡到Broker的?

目录 1. Topic 和 MessageQueue 的基本概念 1.1 Topic 1.2 MessageQueue 2. Topic 和 MessageQueue 的分布 2.1 Topic 的创建 2.2 MessageQueue 分配到 Broker 2.3 分布规则 3. 负载均衡机制 3.1 Producer 的负载均衡 3.2 Consumer 的负载均衡 3.3 Broker 的负载均衡…...

Qt简单迷宫游戏

目录 你将学到你将准备你将改变你将设计你将编程开始界面游玩界面胜利界面其它bug修复 你可扩展下一篇博客要说的东西 你将学到 Qt中QKeySequence对象的基本创建Qt中QShortcut对象的基本应用Qt中QSoundEffect对象的基本应用 你将准备 在开始制作Qt简单迷宫游戏之前&#xff…...

Webrtc (1) - Windows 编译

最近项目上遇到webrtc wgc 的几个test case无法通过&#xff0c;与webrtc人员沟通后决定要自行修复一下(因为他们不想管…) 参考文档 https://webrtc.org/support/contributinghttps://chromium.googlesource.com/chromium/src//main/docs/#checking-out-and-building 以上两…...

深圳大学-智能网络与计算-实验一:RFID原理与读写操作

实验目的与要求 掌握超高频RFID标签的寻卡操作。掌握超高频RFID标签的读写操作。掌握超高频RFID标签多张卡读取时的防冲突机制。 方法&#xff0c;步骤 软硬件的连接与设置超高频RFID寻卡操作超高频RFID防冲突机制超高频RFID读写卡操作 实验过程及内容 一&#xff0e;软硬…...

文献引用指南ChatGPT提示词分享

文献引用指南 在学术写作中&#xff0c;准确引用是至关重要的环节。它不仅能够为您的研究提供坚实的学术基础&#xff0c;还能确保您尊重并认可他人的学术成果&#xff0c;从而有效避免抄袭的问题。而ChatGPT在这一方面同样能够为您提供有力的支持。借助ChatGPT&#xff0c;您…...

什么是计算机应用基础知识

计算机应用基础知识是指学习和掌握计算机的基本理论、硬件、软件、网络和应用技能的基础内容。它是为使用计算机进行日常工作、学习和解决实际问题打下的基础。计算机应用基础知识涉及多个领域,主要包括以下几个方面: 一、计算机硬件基础 计算机硬件组成:了解计算机的基本组…...

SpringBoot集成Flink-CDC,实现对数据库数据的监听

一、什么是 CDC &#xff1f; CDC 是Change Data Capture&#xff08;变更数据获取&#xff09;的简称。 核心思想是&#xff0c;监测并捕获数据库的变动&#xff08;包括数据或数据表的插入、 更新以及删除等&#xff09;&#xff0c;将这些变更按发生的顺序完整记录下来&…...

微信小程序云开发服务端存储API 从云存储空间删除文件

deleteFile 从云存储空间删除文件 const cloud require(wx-server-sdk)exports.main async (event, context) > {const fileIDs [xxx, xxx]const result await cloud.deleteFile({fileList: fileIDs,})return result.fileList }写的资式如有不对&#xff0c;请各位大神多…...

[操作系统] 深入进程地址空间

程序地址空间回顾 在C语言学习的时&#xff0c;对程序的函数、变量、代码等数据的存储有一个大致的轮廓。在语言层面上存储的地方叫做程序地址空间&#xff0c;不同类型的数据有着不同的存储地址。 下图为程序地址空间的存储分布和和特性&#xff1a; 使用以下代码来验证一下…...

gitlab处理空文件夹的提交或空文件夹提交失败

问题描述 厂家发给了我一个压缩包文件&#xff0c;压缩包解压之后本地编译没问题&#xff1b;推送到gitlab之后&#xff0c;再编译就报错了&#xff1b; 问题原因 经过分析之后发现&#xff0c;压缩包解压之后存在很多空文件夹&#xff1b;但是gitlab推送的时候&#xff0c;…...

C++ —— 智能指针 unique_ptr (上)

C —— 智能指针 unique_ptr &#xff08;上&#xff09; 普通指针的不足普通指针的释放智能指针智能指针 unique_ptr智能指针初始化错误用法get()方法返回裸指针智能指针不支持指针的运算&#xff08;、-、、- -&#xff09; 普通指针的不足 new和new [] 的内存需要用delete和…...

ruoyi-vue-pro集成magic-api(图文代码)

目录 前言1. 配置依赖2. 集成登录3. 成功展示前言 🤟 找工作,来万码优才:👉 #小程序://万码优才/r6rqmzDaXpYkJZF 原先写过简单的集成:了解 magic-api的基本用法 附实战代码 magic-api相关文档推荐阅读:接口鉴权 相关的Java代码推荐阅读: java框架 零基础从入门到精…...

【线上问题定位处理】及【性能优化】系列文章

目录 性能优化 性能优化 九大服务架构性能优化方式 如何进行GC调优 如何排查线上系统出现的Full GC MySQL - 性能优化 MySQL - 分库分表 大数据查询的处理方案 MySQL优化手段有哪些 服务CPU100%问题如何快速定位? 服务内存OOM问题如何快速定位? JVM调优6大步骤 线…...

如何解压rar格式文件?8种方法(Win/Mac/手机/网页端)

RAR 文件是一种常见的压缩文件格式&#xff0c;由尤金・罗谢尔&#xff08;Eugene Roshal&#xff09;开发&#xff0c;因其扩展名 “rar” 而得名。它通过特定算法将一个或多个文件、文件夹进行压缩&#xff0c;大幅减小存储空间&#xff0c;方便数据传输与备份。然而&#xf…...

GORM 支持的数据库解析

GORM 是一个流行的 Go 语言 ORM&#xff08;对象关系映射&#xff09;库&#xff0c;它简化了 Go 与数据库之间的交互。作为一款功能强大的库&#xff0c;GORM 支持多种主流关系型数据库&#xff0c;满足不同开发场景下的需求。本文将探讨 GORM 支持的主要数据库及其特点&#…...

分布式光纤应变监测是一种高精度、分布式的监测技术

一、土木工程领域 桥梁结构健康监测 主跨应变监测&#xff1a;在大跨度桥梁的主跨部分&#xff0c;如悬索桥的主缆、斜拉桥的斜拉索和主梁&#xff0c;分布式光纤应变传感器可以沿着这些关键结构部件进行铺设。通过实时监测应变情况&#xff0c;能够精确捕捉到车辆荷载、风荷…...

如何在oracle关闭情况下如何修改spfile的参数

如何在oracle关闭情况下如何修改spfile的参数 一、问题背景二、处理方案 一、问题背景 在ORACLE数据库启动状态下通过下列代码修改了最大连接数 alter system set processes2000 scopespfile sid*;关闭了数据库再重新启动提示如下报错&#xff1a; ORA-00838: Specified valu…...

[ Spring ] Spring Cloud Gateway 2025 Comprehensive Overview

文章目录 Spring Gateway ArchitectureProject Level DependencyService CenterService ProviderGateway ServiceLaunch All Service Spring Gateway Architecture Service Center : register and find service providerService Provider : programs that provide actual serv…...

软考信安27~Windows操作系统安全相关

1、Windows账户与组管理 1.1、用户账户查看 whoami #查看当前登录的用户名称 whoami /all #查看当前系统的用户名和组信息,以及SID whoami /user #查看当前用户的SID net user #查看系统中包含哪些用户 wmic useraccount get name,sid #查看…...

2025年数学建模美赛 A题分析(3)楼梯使用方向偏好模型

2025年数学建模美赛 A题分析&#xff08;1&#xff09;Testing Time: The Constant Wear On Stairs 2025年数学建模美赛 A题分析&#xff08;2&#xff09;楼梯磨损分析模型 2025年数学建模美赛 A题分析&#xff08;3&#xff09;楼梯使用方向偏好模型 2025年数学建模美赛 A题分…...

Spring整合Mybatis、junit纯注解

如何创建一个Spring项目 错误问题 不知道什么原因&#xff0c;大概是依赖版本不兼容、java版本不对的问题&#xff0c;折磨了好久就是搞不成。 主要原因看pom.xml配置 pom.xml配置 java版本 由于是跟着22年黑马视频做的&#xff0c;java版本换成了jdk-11&#xff0c;用21以…...

HAM-TTS大模型:基于token的零样本文字转语音分层声学建模

HAM-TTS大模型:基于token的零样本文字转语音分层声学建模 ​​ 吉利自研语音大模型HAM-TTS的全称是:Hierarchical Acoustic Modeling for Token-Based Zero-Shot Text-to-Speech,直译是基于token的零样本文字转语音分层声学建模,是星睿AI大模型体系下的重要一员。顾名思义…...

SpringBoot开发(三)SpringBoot介绍、项目创建、运行

1. SpringBoot 1.1. SpringBoot介绍 Spring Boot给世界程序员带来了春天&#xff0c;越来越多的企业选择使用spring boot来开发他们的软件&#xff0c;因此学习spring boot是科技发展的必然趋势。本门课程将从web最基础的知识点开始讲起&#xff0c;逐步带你攻破spring boot的…...

SQL Server 建立每日自动log备份的维护计划

SQLServer数据库可以使用维护计划完成数据库的自动备份&#xff0c;下面以在SQL Server 2012为例说明具体配置方法。 1.启动SQL Server Management Studio&#xff0c;在【对象资源管理器】窗格中选择数据库实例&#xff0c;然后依次选择【管理】→【维护计划】选项&#xff0…...

git Bash通过SSH key 登录github的详细步骤

1 问题 通过在windows 终端中的通过git登录github 不再是通过密码登录了&#xff0c;需要本地生成一个密钥&#xff0c;配置到gihub中才能使用 2 步骤 &#xff08;1&#xff09;首先配置用户名和邮箱 git config --global user.name "用户名"git config --global…...

软件越跑越慢的原因分析

如果是qt软件&#xff0c;可以用Qt Creator Profiler 作性能监控如果是通过web请求&#xff0c;可以用JMeter监控。 软件运行过程中逐渐变慢的现象&#xff0c;通常是因为系统资源&#xff08;如 CPU、内存、磁盘 I/O 等&#xff09;逐渐被消耗或软件中存在性能瓶颈。这个问题…...

C++AVL树(二)详解

文章目录 AVL树旋转单旋右单旋左单旋 双旋左右双旋右左双旋 平衡因子的更新左右双旋右左双旋 判断是不是AVL树时间复杂度分析全部的代码 AVL树 旋转 单旋 单旋是纯粹的一边高 单旋平衡因子是同号 右单旋 a,b,c自身不能发生旋转 并且也不能不向上继续更新&#xff08;不能停…...

【GoLang】利用validator包实现服务端参数校验时自定义错误信息

在C/S架构下&#xff0c;服务端在校验请求参数时&#xff0c;若出现参数错误&#xff0c;要响应给客户端一个错误消息&#xff0c;通常我们会统一响应“参数错误”。 但是&#xff0c;如果只是一味的提示参数错误&#xff0c;我并不知道具体是哪个参数错了呀&#xff01;能不能…...

AIP-128 声明友好接口

编号128原文链接AIP-128: Declarative-friendly interfaces状态批准创建日期2020-10-06更新日期2020-10-06 许多服务需要与常见的DevOps工具交互&#xff0c;特别是创建和管理可网络寻址资源&#xff08;如虚拟机、负载均衡器、数据库实例等&#xff09;的工具。这些工具采用“…...

【Jave全栈】Java与JavaScript比较

文章目录 前言一、Java1、 历史与背景2、语言特点3、应用场景4、生态系统 二、JavaScript1、历史与背景2、语言特点3、应用场景4、 生态系统 三、相同点四、不同点1、语言类型2、用途3、语法和结构4、性能5、生态系统6、开发模式 前言 Java和JavaScript是两种不同的编程语言&a…...

钉钉群机器人设置——python版本

钉钉群机器人设置——python版本 应用场景钉钉界面操作程序开发效果展示 应用场景 由于工作需要&#xff0c;很多项目执行程序后出现报错信息无法第一时间收到&#xff0c;因此实时预警对于监控程序还是有必要。&#xff08;仅个人观点&#xff09; 参考文档及博客&#xff1a…...

报错:{‘csrf_token‘: [‘The CSRF token is missing.‘]}

flask实现一个简单的注册界面报错 register.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head> <body> <form action"" method"post&…...

STM32新建不同工程的方式

新建工程的方式 1. 安装开发工具 MDK5 / keil52. CMSIS 标准3. 新建工程3.1 寄存器版工程3.2 标准库版工程3.3 HAL/LL库版工程3.4 HAL库、LL库、标准库和寄存器对比3.5 库开发和寄存器的关系 4. STM32CubeMX工具的作用 1. 安装开发工具 MDK5 / keil5 MDK5 由两个部分组成&#…...

Java数据库操作指南:快速上手JDBC【学术会议-2025年数字化教育与信息技术(DEIT 2025】

大会官网&#xff1a;www.ic-deit.org 前言 在现代企业应用中&#xff0c;数据库是数据存储和管理的重要组成部分。Java作为一种广泛使用的编程语言&#xff0c;提供了多种方式与数据库进行交互。本文将介绍 JDBC&#xff08;Java Database Connectivity&#xff09;&#x…...

基于Springboot + vue实现的在线装修管理系统

“前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff1a;人工智能学习网站” &#x1f496;学习知识需费心&#xff0c; &#x1f4d5;整理归纳更费神。 &#x1f389;源码免费人人喜…...

计算机网络之应用层

本文章目录结构出自于《王道计算机考研 计算机网络_哔哩哔哩_bilibili》 05 应用层 在网上看到其他人做了相关笔记&#xff0c;就不再多余写了&#xff0c;直接参考着学习吧。 王道考研 计算机网络笔记 第六章&#xff1a;应用层_王道考研 应用层 笔记-CSDN博客 DNS&#x…...

SpringMVC框架

第1章 SpringMVC入门 1.1 SpringMVC简介 Spring MVC 全称:Spring Web MVC是 Spring 框架的一部分&#xff0c;专注于实现 Web 应用程序的模型-视图-控制器&#xff08;Model-View-Controller, MVC&#xff09;设计模式。它为构建灵活且松耦合的 Web 应用提供了强大的功能&…...

将 OneLake 数据索引到 Elasticsearch - 第 1 部分

作者&#xff1a;来自 Elastic Gustavo Llermaly 学习配置 OneLake&#xff0c;使用 Python 消费数据并在 Elasticsearch 中索引文档&#xff0c;然后运行语义搜索。 OneLake 是一款工具&#xff0c;可让你连接到不同的 Microsoft 数据源&#xff0c;例如 Power BI、Data Activ…...