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

【小沐学前端】Node.js实现基于Protobuf协议的WebSocket通信

文章目录

  • 1、简介
    • 1.1 Node
    • 1.2 WebSocket
    • 1.3 Protobuf
  • 2、安装
    • 2.1 Node
    • 2.2 WebSocket
      • 2.2.1 nodejs-websocket
      • 2.2.2 ws
    • 2.3 Protobuf
  • 3、代码测试
    • 3.1 例子1:websocket(html)
      • 3.1.1 客户端:yxy_wsclient1.html
      • 3.1.2 客户端:yxy_wsclient1_2.html
    • 3.2 例子2:websocket(js)
      • 3.2.1 服务端:yxy_wsserver2.js
      • 3.2.2 客户端:yxy_wsclient2.js
    • 3.3 例子3:websocket(js+html)
      • 3.3.1 服务端:yxy_wsserver3.js
      • 3.3.2 客户端:yxy_wsclient3.html
      • 3.3.3 客户端:yxy_wsclient3_2.html
      • 3.3.4 客户端:yxy_wsclient3_3.html
    • 3.4 例子4:websocket(js+proto)
      • 3.4.1 服务端:yxy_wsserver4.js
      • 3.4.2 客户端:yxy_wsclient4.js
    • 3.5 例子5:websocket(js+express)
      • 3.5.1 服务端:yxy_wsserver5.js
      • 3.5.2 客户端:yxy_wsclient5.html
  • 结语

1、简介

1.1 Node

Node.js发布于2009年5月,由Ryan Dahl开发,是一个基于Chrome V8引擎的JavaScript运行环境,使用了一个事件驱动、非阻塞式I/O模型,让JavaScript 运行在服务端的开发平台,它让JavaScript成为与PHP、Python、Perl、Ruby等服务端语言平起平坐的脚本语言。
在这里插入图片描述
简单的说 Node.js 就是运行在服务端的 JavaScript。

Node.js 是一个基于 Chrome JavaScript 运行时建立的一个平台。

Node.js 是一个事件驱动 I/O 服务端 JavaScript 环境,基于 Google 的 V8 引擎,V8 引擎执行 Javascript 的速度非常快,性能非常好。

1.2 WebSocket

https://developer.mozilla.org/zh-CN/docs/Web/API/WebSocket

WebSocket是一个长连接,客户端可以给服务端发送消息,服务端也可以给客户端发送消息,这便是全双工通信。

WebSocket是html5规范中的一个部分,它借鉴了socket这种思想,为web应用程序客户端和服务端之间(注意是客户端服务端)提供了一种全双工通信机制。同时,它又是一种新的应用层协议,WebSocket协议是为了提供web应用程序和服务端全双工通信而专门制定的一种应用层协议,通常它表示为:ws://echo.websocket.org/?encoding=text HTTP/1.1。通俗的讲,WebSocket 是一种新的网络通信协议,现在浏览器端很多高级功能都需要用到它。
在这里插入图片描述

WebSockets 是一种先进的技术。它可以在用户的浏览器和服务器之间打开交互式通信会话。使用此 API,你可以向服务器发送消息并接收事件驱动的响应,而无需通过轮询服务器的方式以获得响应。

WebSocket 是一种网络传输协议,可在单个 TCP 连接上进行全双工通信,位于 OSI 模型的应用层。WebSocket 协议在 2011 年由 IETF 标准化为 RFC 6455,后由 RFC 7936 补充规范。

WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输。

1.3 Protobuf

Google Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化。它很适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。
https://github.com/protocolbuffers/protobuf
在这里插入图片描述
Protobuf (Protocol Buffers) 是谷歌开发的一款无关平台,无关语言,可扩展,轻量级高效的序列化结构的数据格式,用于将自定义数据结构序列化成字节流,和将字节流反序列化为数据结构。所以很适合做数据存储和为不同语言,不同应用之间互相通信的数据交换格式,只要实现相同的协议格式,即后缀为proto文件被编译成不同的语言版本,加入各自的项目中,这样不同的语言可以解析其它语言通过Protobuf序列化的数据。
在这里插入图片描述

2、安装

2.1 Node

https://nodejs.org/en

在这里插入图片描述

2.2 WebSocket

下面给出了WebSocket数据帧的统一格式。

0                   1                   2                   30 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len |    Extended payload length    |
|I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
|N|V|V|V|       |S|             |   (if payload len==126/127)   |
| |1|2|3|       |K|             |                               |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
|     Extended payload length continued, if payload len == 127  |
+ - - - - - - - - - - - - - - - +-------------------------------+
|                               |Masking-key, if MASK set to 1  |
+-------------------------------+-------------------------------+
| Masking-key (continued)       |          Payload Data         |
+-------------------------------- - - - - - - - - - - - - - - - +
:                     Payload Data continued ...                :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
|                     Payload Data continued ...                |
+---------------------------------------------------------------+

2.2.1 nodejs-websocket

https://www.npmjs.com/package/nodejs-websocket

用于 websocket 服务器和客户端的 nodejs 模块

安装库nodejs-websocket:

npm i nodejs-websocket

查看库nodejs-websocket 的当前本地安装版本:

npm ls nodejs-websocket -g

在这里插入图片描述

  • 入门示例
var ws = require("nodejs-websocket")// Scream server example: "hi" -> "HI!!!"
var server = ws.createServer(function (conn) {console.log("New connection")conn.on("text", function (str) {console.log("Received "+str)conn.sendText(str.toUpperCase()+"!!!")})conn.on("close", function (code, reason) {console.log("Connection closed")})
}).listen(8001)

2.2.2 ws

https://www.npmjs.com/package/ws

ws: a Node.js WebSocket library
ws 是一个简单易用、速度快、经过全面测试的 WebSocket 客户端和 服务器实现。

或者安装库ws:

npm i ws

查看库ws的当前本地安装版本:

npm ls ws -g

在这里插入图片描述

2.3 Protobuf

https://github.com/protobufjs/protobuf.js/

Protocol Buffers for JavaScript (& TypeScript).

在这里插入图片描述
安装库protobufjs :

npm install protobufjs [--save --save-prefix=~]
npm install protobufjs-cli [--save --save-prefix=~]

查看库protobufjs 的当前本地安装版本:

npm ls protobufjs -g

在这里插入图片描述

3、代码测试

3.1 例子1:websocket(html)

3.1.1 客户端:yxy_wsclient1.html

  • yxy_wsclient1.html
var ws = new WebSocket("wss://echo.websocket.org");ws.onopen = function(evt) { console.log("Connection open ..."); ws.send("Hello WebSockets!");
};ws.onmessage = function(evt) {console.log( "Received Message: " + evt.data);ws.close();
};ws.onclose = function(evt) {console.log("Connection closed.");
};

3.1.2 客户端:yxy_wsclient1_2.html

  • yxy_wsclient1.html
// Create WebSocket connection.
const socket = new WebSocket("ws://localhost:8080");// Connection opened
socket.addEventListener("open", function (event) {socket.send("Hello Server!");
});// Listen for messages
socket.addEventListener("message", function (event) {console.log("Message from server ", event.data);
});

3.2 例子2:websocket(js)

3.2.1 服务端:yxy_wsserver2.js

const WebSocket = require('ws');//引入模块const wss = new WebSocket.Server({ port: 8080 });//创建一个WebSocketServer的实例,监听端口8080wss.on('connection', function connection(ws) {ws.on('message', function incoming(message) {console.log('received: %s', message);ws.send('Hi Client');});//当收到消息时,在控制台打印出来,并回复一条信息});

3.2.2 客户端:yxy_wsclient2.js

const WebSocket = require('ws');const ws = new WebSocket('ws://localhost:8080');ws.on('open', function open() {ws.send('Hi Server');
});//在连接创建完成后发送一条信息ws.on('message', function incoming(data) {console.log(data);
});//当收到消息时,在控制台打印出来

3.3 例子3:websocket(js+html)

3.3.1 服务端:yxy_wsserver3.js

  • yxy_wsserver3.js
var ws = require("nodejs-websocket")
var PORT = 3000var server = ws.createServer(function (conn) {console.log("New connection")conn.on("text", function (str) {console.log("Received "+str)conn.sendText(str.toUpperCase()+"!!!")})conn.on("close", function (code, reason) {console.log("Connection closed")})conn.on("error",function(err){console.log('handler error')console.log(err)})
}).listen(PORT)console.log('websocket server listening on port ' + PORT)
  • 运行结果如下:
    在这里插入图片描述

3.3.2 客户端:yxy_wsclient3.html

  • yxy_wsclient3.html
<html>
<head><meta charset="utf-8"/><title>websocket</title>
</head>
<body><h1>Echo test</h1><input id="sendTxt" type="text"/><button id="sendBtn">发送</button><div id="recv"></div><script type="text/javascript">// var websocket = new WebSocket("ws://echo.websocket.org/");var websocket = new WebSocket("ws://127.0.0.1:3000");websocket.onopen = function(){console.log('websocket open');document.getElementById('recv').innerHTML = 'Connected';}websocket.onclose = function(){console.log('websocket close');}websocket.onmessage = function(event){console.log(event.data);document.getElementById('recv').innerHTML = event.data;}document.getElementById('sendBtn').onclick = function(){var txt = document.getElementById('sendTxt').value;websocket.send(txt);}</script>
</body>
  • 运行结果如下:
    在这里插入图片描述

3.3.3 客户端:yxy_wsclient3_2.html

  • yxy_wsclient3_2.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>WenSocket</title><style>div{width: 200px;height: 200px;border:1px solid;margin-top: 5px;}</style>
</head>
<body><input type="text" placeholder="请输入内容"><button>提交</button><div></div><script>const input = document.querySelector('input')const button = document.querySelector('button')const div = document.querySelector('div')//创建WebSocket实例// const socket = new WebSocket("ws://echo.websocket.org")const socket = new WebSocket("ws://127.0.0.1:3000")//监听服务是否链接socket.addEventListener('open',()=>{div.innerHTML = "服务链接成功"})//button触发点击事件,将input框中的内容发送至websocket//查看websocket是否接收到数据:chrome F12打开控制台》Network》WS》echo.websocket.org》messagesbutton.addEventListener('click',()=>{const value = input.valuesocket.send(value)})// 将接收到的数据插入到div中socket.addEventListener('message',(e)=>{console.log(e)div.innerHTML = e.data})</script>
</body>
</html>
  • 运行结果如下:
    在这里插入图片描述

3.3.4 客户端:yxy_wsclient3_3.html

  • yxy_wsclient3_3.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>WebSocket</title><style></style>
</head>
<body><input type="text" placeholder="请输入内容"><button>提交</button><div></div><script>const input = document.querySelector('input')const button = document.querySelector('button')const div = document.querySelector('div')const socket = new WebSocket('ws://127.0.0.1:3000')socket.addEventListener('open',()=>{div.innerText = "欢迎来到聊天室"})button.addEventListener('click',()=>{const value = input.valuesocket.send(value)input.value = ''})socket.addEventListener('message',(e)=>{//div.innerText = e.data //这种方法会覆盖原先的数据const dv = document.createElement('div')dv.innerText = e.datadiv.appendChild(dv)})</script>
</body>
</html>

在这里插入图片描述

3.4 例子4:websocket(js+proto)

WebSocket是HTML5新增的协议,它的目的是在浏览器和服务器之间建立一个不受限的双向通信的通道,比如说,服务器可以在任意时刻发送消息给浏览器。任何一方都可以主动发消息给对方。

HTTP协议是一个请求-响应协议,请求必须先由浏览器发给服务器,服务器才能响应这个请求,再把数据发送给浏览器。换句话说,浏览器不主动请求,服务器是没法主动发数据给浏览器的。

WebSocket并不是全新的协议,而是利用了HTTP协议来建立连接。

安装ws库:

npm i ws
  • user.proto
syntax = "proto3";
package yxy;message Login {required string name = 1;required string pwd = 2;
}
message Address{string province = 1;string city = 2;string country = 3;
}

3.4.1 服务端:yxy_wsserver4.js

  • yxy_wsserver4.js

const protobuf = require("protobufjs");
const PORT = 3000;
const HOST = '127.0.0.1';protobuf.load("./user.proto", (err, root) => {if (err) throw err;const LoginMessage = root.lookupType("yxy.Login");const WebSocket = require('ws')const WebSocketServer = WebSocket.Server;const wss =new WebSocketServer({port:PORT})//如果有WebSocket请求接入,wss对象可以响应connection事件来处理这个WebSocket:wss.on('connection',function(ws){  //在connection事件中,回调函数会传入一个WebSocket的实例,表示这个WebSocket连接。console.log(`[SERVER] connection()`);ws.on('message',function(message){console.log(`[SERVER] Received:${message}`);// 解码数据 const payload = LoginMessage.decode(message);// 在这里处理消息console.log(payload);// 编码响应 const responseData = LoginMessage.encode({name: "杨小羊",pwd: "111111"}).finish();const msg = responseData.toString();ws.send(`ECHO:${msg}` ,(err)=>{if(err){console.log(`[SERVER] error:${err}`);}})})})
});
  • 运行结果如下:
    在这里插入图片描述

3.4.2 客户端:yxy_wsclient4.js

  • yxy_wsclient4.js
const protobuf = require("protobufjs");
const PORT = 3000;
const HOST = '127.0.0.1';protobuf.load("./user.proto", (err, root) => {if (err) throw err;const LoginMessage = root.lookupType("yxy.Login");const WebSocket = require('ws')let ws = new WebSocket('ws://localhost:3000');// 打开WebSocket连接后立刻发送一条消息:ws.on('open', function () {console.log(`[CLIENT] open()`);//每隔一秒向服务器发送消息,以便后面每隔一秒收到消息setInterval(function(){// 编码数据 const data = LoginMessage.encode({name: "爱看书的小沐",pwd: "222222"}).finish();// 将数据写到连接 ws.send(data);console.log(`[CLIENT] Send: ${data}`);},1000)});// 响应收到的消息:ws.on('message', function (message) {console.log(`[CLIENT] Received: ${message}`);const loginResponse = LoginMessage.decode(message);console.log(loginResponse);})
});
  • 运行结果如下:
    在这里插入图片描述

3.5 例子5:websocket(js+express)

3.5.1 服务端:yxy_wsserver5.js

  • yxy_wsserver5.js
var app = require('express')();
var server = require('http').Server(app);
var WebSocket = require('ws');var wss = new WebSocket.Server({port: 8080
});wss.on('connection', function connection(ws) {console.log('server: receive connection.');ws.on('message', function incoming(message) {console.log('server: received: %s', message);});ws.send('world');
});app.get('/', function (req, res) {res.sendfile(__dirname + '/index.html');
});app.listen(3000);

在这里插入图片描述

3.5.2 客户端:yxy_wsclient5.html

  • yxy_wsclient5.html
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>WebSocket</title><style></style>
</head><body><script>var ws = new WebSocket('ws://localhost:8080');ws.onopen = function () {console.log('ws onopen');ws.send('from client: hello');};ws.onmessage = function (e) {console.log('ws onmessage');console.log('from server: ' + e.data);};
</script></body>
</html>

结语

如果您觉得该方法或代码有一点点用处,可以给作者点个赞,或打赏杯咖啡;╮( ̄▽ ̄)╭
如果您感觉方法或代码不咋地//(ㄒoㄒ)//,就在评论处留言,作者继续改进;o_O???
如果您需要相关功能的代码定制化开发,可以留言私信作者;(✿◡‿◡)
感谢各位大佬童鞋们的支持!( ´ ▽´ )ノ ( ´ ▽´)っ!!!

相关文章:

【小沐学前端】Node.js实现基于Protobuf协议的WebSocket通信

文章目录 1、简介1.1 Node1.2 WebSocket1.3 Protobuf 2、安装2.1 Node2.2 WebSocket2.2.1 nodejs-websocket2.2.2 ws 2.3 Protobuf 3、代码测试3.1 例子1&#xff1a;websocket&#xff08;html&#xff09;3.1.1 客户端&#xff1a;yxy_wsclient1.html3.1.2 客户端&#xff1a…...

MySQL学习笔记24

MySQL的物理备份&#xff1a; xtrabackup备份介绍&#xff1a; xtrabackup优缺点&#xff1a; 优点&#xff1a; 1、备份过程快速、可靠&#xff08;因为是物理备份&#xff09;&#xff1b;直接拷贝物理文件。 2、支持增量备份&#xff0c;更为灵活&#xff1b; 3、备份…...

objective-c 基础学习

目录 第一节&#xff1a;OC 介绍 ​​第二节&#xff1a;Fundation 框架 ​第三节&#xff1a;NSLog 相对于print 的增强 ​第四节&#xff1a;NSString ​第五节&#xff1a;oc新增数据类型 第六节&#xff1a; 类和对象 ​类的方法的声明与实现 ​第七节&#xff1a;类…...

【精彩回顾】 用sCrypt在Bitcoin上构建智能合约

2023年3月24日&#xff0c;sCrypt在英国Exeter大学举办了关于智能合约的大学讲学。sCrypt首席执行官刘晓晖做了题为“用sCrypt在Bitcoin上构建智能合约”的演讲&#xff0c;并与到场的老师、学生进行了深入交流、互动。这次课程着重讲解了 BSV 智能合约的基础概念&#xff0c;以…...

Kotlin 使用泛型

在 Kotlin 中&#xff0c;我们可以使用泛型&#xff08;Generics&#xff09;来编写具有通用性的代码&#xff0c;以增强代码的可重用性和类型安全性。通过使用泛型&#xff0c;我们可以在不指定具体类型的情况下编写适用于多种类型的函数和类。 以下是 Kotlin 中使用泛型的几…...

深度学习 二:COVID 19 Cases Prediction (Regression)

Deep Learning 1. 回归算法思路2. 代码2.1 基础操作2.2 定义相关函数2.3.1 定义图像绘制函数2.3.2 数据集加载及预处理2.3.3 构造数据加载器2.3.4 构建前馈神经网络&#xff08;Feedforward Neural Network&#xff09;模型2.3.5 神经网络的训练过程2.3.6 模型评估2.3.7 模型测…...

UG\NX二次开发 信息窗口的4种输出方式 NXOpen::ListingWindow::DeviceType

文章作者:里海 来源网站:《里海NX二次开发3000例专栏》 简介 UG\NX二次开发 信息窗口的4种输出方式 NXOpen::ListingWindow::DeviceType 信息窗口的输出类型 enum NXOpen::ListingWindow::DeviceType 枚举值描述 DeviceTypeWindow0输出将写入“信息”窗口DeviceTypeFile1输出…...

mavn打包时如何把外部依赖加进去?

一、添加依赖: <dependency><groupId>com.dm</groupId><artifactId>DmJdbcDriver</artifactId><version>18</version><scope>system</scope><systemPath>${project.basedir}/lib/DmJdbcDriver18.jar</systemP…...

爬虫代理请求转换selenium添加带有账密的socks5代理

爬虫代理请求转换selenium添加带有账密的socks5代理。 一、安装三方库 二、使用方法 1、在cmd命令行输入&#xff1a; 2、给selenium添加代理 最近因为工作需要&#xff0c;需要selenium添加带有账密的socks5代理&#xff0c;贴出一个可用的方法。 把带有账密的socks5代理&am…...

Redis 如何实现数据不丢失的?

Redis 实现数据不丢失的关键在于使用了多种持久化机制,以确保数据在内存和磁盘之间的持久性。以下是 Redis 实现数据不丢失的主要方法: 快照(Snapshot)持久化: Redis 使用快照持久化来定期将内存中的数据写入磁盘。快照是一个数据库状态的副本,包含了所有键和与其相关联的…...

[高等数学]同济版高等数学【第七版】上下册教材+习题全解PDF

laiyuan 「高等数学 第7版 同济大学」 https://www.aliyundrive.com/s/5fpFJb3asYk 提取码: 61ao 通过百度网盘分享的文件&#xff1a;同济版高数教材及… 链接:https://pan.baidu.com/s/1gyy-GMGjwguAjYijrpC8RA?pwdyhnr 提取码:yhnr 高等数学相关&#xff1a; The Ca…...

【面试题精讲】Java超过long类型的数据如何表示

有的时候博客内容会有变动&#xff0c;首发博客是最新的&#xff0c;其他博客地址可能会未同步,认准https://blog.zysicyj.top 首发博客地址[1] 面试题手册[2] 系列文章地址[3] 在 Java 中&#xff0c;如果需要表示超过 long 类型范围的数据&#xff0c;可以使用 BigInteger 类…...

Shapiro-Wilk正态性检验(Shapiro和Wilk于1965年提出)

Shapiro-Wilk正态性检验是一种用于确定数据集是否服从正态分布的统计方法。它基于Shapiro和Wilk于1965年提出的检验统计量。以下是其基本原理和用途&#xff1a; 基本原理&#xff1a; 零假设&#xff08;Null Hypothesis&#xff09;&#xff1a;Shapiro-Wilk检验的零假设是数…...

debian设置允许ssh连接

解决新debian系统安装后不能通过ssh连接的问题。 默认情况下&#xff0c;Debian系统不开启SSH远程登录&#xff0c;需要手动安装SSH软件包并设置开机启动。 > 设置允许root登录传送门&#xff1a;debian设置允许root登录 首先检查/etc/ssh/sshd_config文件是否存在。 注意…...

【C语言经典100例题-66】(用指针解决)输入3个数a,b,c,按大小顺序输出。

代码&#xff1a; #include<stdio.h> #define _CRT_SECURE_NO_WARNINGS 1//VS编译器使用scanf函数时会报错&#xff0c;所以添加宏定义 swap(p1, p2) int* p1, * p2; {int p;p *p1;*p1 *p2;*p2 p; } int main() {int n1, n2, n3;int* pointer1, * pointer2, * point…...

【STM32 CubeMX】移植u8g2(一次成功)

文章目录 前言一、下载u8g2源文件二、复制和更改文件2.1 复制文件2.2 修改文件u8g2_d_setup文件u8g2_d_memory 三、编写oled.c和oled.h文件3.1 CubeMX配置I2C3.2 编写文件oled.holed.c 四、测试代码main函数测试代码 总结 前言 在本文中&#xff0c;我们将介绍如何在STM32上成…...

华为云智能化组装式交付方案 ——金融级PaaS业务洞察及Web3实践的卓越贡献

伴随信息技术与金融业务加速的融合&#xff0c;企业应用服务平台&#xff08;PaaS&#xff09;已从幕后走向台前&#xff0c;成为推动行业数字化转型的关键力量。此背景下&#xff0c;华为云PaaS智能化组装式交付方案闪耀全场&#xff0c;在近日结束的华为全联接大会 2023上倍受…...

Halcon Image相关算子(二)

(1) dyn_threshold(OrigImage, ThresholdImage : RegionDynThresh : Offset, LightDark : ) 功能&#xff1a;从输入图像中选择像素满足阈值条件的那些区域。 图形输入参数&#xff1a;OrigImage&#xff1a;原始图像&#xff1b; 图形输入参数&#xff1a;ThresholdImage&a…...

Rust 多线程编程

一个进程一定有一个主线程&#xff0c;主线程之外创建出来的线程称为子线程 多线程编程&#xff0c;其实就是在主线程之外创建子线程&#xff0c;让子线程和主线程并发运行&#xff0c;完成各自的任务。 Rust语言支持多线程编程。 Rust语言标准库中的 std::thread 模块用于多线…...

JavaScript高阶班之ES6 → ES11(八)

JavaScript高阶班之ES6 → ES11 1、ES6新特性1.1、let 关键字1.2、const关键字1.3、变量的解构赋值1.3.1、数组的解构赋值1.3.2、对象的解构赋值 1.4、模板字符串1.5、简化对象写法1.6、箭头函数1.7、函数参数默认值1.8、rest参数1.9、spread扩展运算符1.9.1、数组合并1.9.2、数…...

从K8S配置到前端实现:用Vue3+Codemirror打造专业级YAML编辑器全流程

从K8S配置到前端实现&#xff1a;用Vue3Codemirror打造专业级YAML编辑器全流程 在云原生技术栈中&#xff0c;YAML文件如同空气般无处不在——从Kubernetes集群部署到CI/CD流水线配置&#xff0c;这种人类可读的数据序列化格式已成为基础设施即代码的核心载体。但当我们面对动辄…...

YOLOv8与YOLOv11网络结构对比:从yolov8.yaml到yolo11.yaml的演进与优化

YOLOv8与YOLOv11网络结构深度对比&#xff1a;从架构设计到性能优化 在计算机视觉领域&#xff0c;目标检测技术一直是研究热点&#xff0c;而YOLO(You Only Look Once)系列作为其中的佼佼者&#xff0c;以其高效的实时检测能力广受关注。本文将深入剖析YOLOv8与YOLOv11的网络结…...

MacOS自动操作神器:3个隐藏功能一键搞定桌面整理(附脚本)

MacOS自动操作神器&#xff1a;3个隐藏功能一键搞定桌面整理&#xff08;附脚本&#xff09; 每次打开Mac电脑&#xff0c;看到满屏的文件和图标&#xff0c;是不是感觉工作效率瞬间降了一半&#xff1f;特别是视频创作者和设计师&#xff0c;桌面上经常堆满素材和半成品&#…...

DanKoe 视频笔记:致富之路:三个关键决策

在本节课中&#xff0c;我们将要学习决定个人能否实现财富积累的三个核心决策。这些决策并非关于具体的赚钱技巧&#xff0c;而是关于如何从根本上重塑你的思维方式和行为模式&#xff0c;为创造财富铺平道路。 概述 许多人渴望财富&#xff0c;但往往不得其法。真正的致富之…...

UI-Grid终极样式定制指南:10个LESS变量和主题系统使用技巧

UI-Grid终极样式定制指南&#xff1a;10个LESS变量和主题系统使用技巧 【免费下载链接】ui-grid UI Grid: an Angular Data Grid 项目地址: https://gitcode.com/gh_mirrors/ui/ui-grid UI-Grid作为Angular数据表格的强大解决方案&#xff0c;提供了灵活的样式定制系统。…...

深求·墨鉴(DeepSeek-OCR-2)惊艳效果:书法题跋+钤印位置+行气关系可视化还原

深求墨鉴&#xff08;DeepSeek-OCR-2&#xff09;惊艳效果&#xff1a;书法题跋钤印位置行气关系可视化还原 1. 引言&#xff1a;当OCR遇见水墨美学 你有没有遇到过这样的场景&#xff1f;面对一幅珍贵的书法作品或古籍文献&#xff0c;想要将其中的文字内容数字化&#xff0…...

Flutter 鸿蒙(OpenHarmony)化适配实战:从零实现「点击按钮退出应用」插件

一、引言 随着鸿蒙生态的持续发展&#xff0c;Flutter 作为跨平台开发的主流框架&#xff0c;对鸿蒙系统的支持也越来越完善。很多 Flutter 开发者在迁移鸿蒙应用时&#xff0c;都会遇到「应用退出」的基础需求&#xff1a;点击按钮直接关闭应用&#xff0c;回到系统桌面。 本…...

SSM+JSP动漫网站源码+论文

代码可以查看文章末尾⬇️联系方式获取&#xff0c;记得注明来意哦~&#x1f339; 分享万套开题报告任务书答辩PPT模板 作者完整代码目录供你选择&#xff1a; 《SpringBoot网站项目》1800套 《SSM网站项目》1500套 《小程序项目》1600套 《APP项目》1500套 《Python网站项目》…...

CPython AOT编译器模块全图谱,从_pycompile.c到aot_codegen.cc的17个关键函数逐行注释与性能拐点分析

第一章&#xff1a;CPython AOT编译器模块全图谱概览与演进脉络CPython 的 Ahead-of-Time&#xff08;AOT&#xff09;编译能力并非原生内建&#xff0c;而是近年来通过社区驱动的实验性项目逐步构建起模块化支撑体系。其核心演进路径始于 PEP 698 提出的字节码预编译增强机制&…...

OpenClaw数据清洗:Qwen3-4B-Thinking-2507-GPT-5-Codex-Distill-GGUF处理混乱CSV文件

OpenClaw数据清洗&#xff1a;Qwen3-4B-Thinking-2507-GPT-5-Codex-Distill-GGUF处理混乱CSV文件 1. 为什么需要自动化数据清洗 上周我接手了一个市场调研项目&#xff0c;客户发来的CSV文件打开就让我头皮发麻——编码混乱、字段名全是大写拼音缩写、日期格式五花八门。手动…...