物联网服务器搭建及部署详细说明:掌握 Node.js、MongoDB、Socket.IO 和 JWT 的实用指南

关键知识点目录

1. 环境准备

1.1 硬件要求

1.2 软件要求

2. 搭建步骤

3. 数据处理与存储

3.1 数据存储

3.2 数据实时处理

3.2.1 安装 Socket.IO

3.2.2 修改服务器代码

4. 安全性

4.1 身份验证与授权

4.2 加密通信

4.2.1 生成自签名证书(开发环境)

4.2.2 修改服务器以支持 HTTPS

5. 数据分析和可视化

5.1 集成 Grafana

5.2.2 图表数据更新

6. 事件处理与报警

6.1 事件检测

7. 接口与集成

7.1 提供 RESTful API

7.1.1 获取所有设备数据

8. 日志与监控

8.1 日志记录

8.2 系统监控

9. 用户管理

9.1 用户角色和权限管理

9.1.1 修改用户模型

9.1.2 修改用户注册接口

9.2 权限控制

9.2.1 创建中间件进行权限检查

9.2.2 修改删除设备接口

9.3 审计和跟踪

9.3.1 修改用户注册接口

9.3.2 修改用户登录接口


物联网(IoT)正在以惊人的速度发展,越来越多的设备连接到互联网。搭建一个物联网服务器是实现设备管理、数据处理和安全性的关键。本文将详细介绍搭建物联网服务器的过程,包括所需的步骤、代码示例和相关工具。

1. 环境准备

在开始搭建物联网服务器之前,确保你的开发环境已准备好。

1.1 硬件要求

  • 服务器:可以使用物理服务器或云服务器(如AWS、Azure、阿里云)。
  • 开发设备:可以是树莓派、Arduino等物联网设备。

1.2 软件要求

  • 操作系统:Ubuntu 20.04或更高版本。
  • 数据库:MySQL或MongoDB。
  • 编程语言:Node.js、Python或Java。
  • 工具:Docker(可选)、Postman(用于测试API)。

2. 搭建步骤

2.1 安装必要的软件

首先,更新系统并安装Node.js和MongoDB。

# 更新系统
sudo apt update && sudo apt upgrade -y# 安装 Node.js
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt install -y nodejs# 安装 MongoDB
sudo apt install -y mongodb

2.2 创建项目目录

创建一个项目目录并初始化Node.js应用。

# 创建项目目录
mkdir IoTServer
cd IoTServer# 初始化Node.js项目
npm init -y

2.3 安装依赖包

安装必要的依赖包,如Express.js(用于构建API)和Mongoose(用于MongoDB交互)。

npm install express mongoose body-parser cors

2.4 编写服务器代码

创建一个名为server.js的文件,并编写基础的Express.js服务器代码。

// server.js
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const cors = require('cors');const app = express();
const PORT = process.env.PORT || 3000;// 连接到MongoDB数据库
mongoose.connect('mongodb://localhost:27017/iot', {useNewUrlParser: true,useUnifiedTopology: true
}).then(() => {console.log('MongoDB connected');
}).catch(err => {console.error('MongoDB connection error:', err);
});// 中间件
app.use(cors());
app.use(bodyParser.json());// 设备模型
const DeviceSchema = new mongoose.Schema({name: String,type: String,status: String
});
const Device = mongoose.model('Device', DeviceSchema);// 设备注册接口
app.post('/api/devices', async (req, res) => {const device = new Device(req.body);await device.save();res.status(201).send(device);
});// 启动服务器
app.listen(PORT, () => {console.log(`Server is running on http://localhost:${PORT}`);
});

2.5 启动服务器

运行服务器代码,确保没有错误。

node server.js

你应该会看到“Server is running on http://localhost:3000”的消息。

2.6 测试设备注册接口

使用Postman或curl测试设备注册接口。

Postman配置

  • 方法:POST
  • URLhttp://localhost:3000/api/devices
  • Body(JSON格式):
{"name": "温度传感器","type": "传感器","status": "在线"
}

点击“Send”,如果一切正常,你将收到新设备的响应。

3. 数据处理与存储

3.1 数据存储

在上述代码中,我们已经使用MongoDB存储设备数据。你可以根据需求添加更多数据处理的功能。

3.2 数据实时处理

为了实现实时数据处理功能,我们将使用 Socket.IO 来实现设备与服务器之间的双向通信。这允许设备在数据发生变化时立即将数据发送到服务器,服务器也可以实时向设备推送消息。

3.2.1 安装 Socket.IO

如果你还没有安装 Socket.IO,可以通过以下命令进行安装:

npm install socket.io

3.2.2 修改服务器代码

在 server.js 文件中,我们已经导入了 Socket.IO。接下来,我们需要修改服务器代码以支持实时数据传输。以下是更新后的代码:

const http = require('http');
const socketIo = require('socket.io');// 创建 HTTP 服务器
const server = http.createServer(app);
const io = socketIo(server);// 监听连接
io.on('connection', (socket) => {console.log('A device connected:', socket.id);// 监听来自设备的数据socket.on('data', async (data) => {console.log('Received data:', data);// 在这里可以进行数据处理或存储// 例如:将数据存入数据库const deviceData = new Device(data);await deviceData.save();// 向所有连接的客户端广播接收到的数据io.emit('data', deviceData);});// 监听断开连接socket.on('disconnect', () => {console.log('Device disconnected:', socket.id);});
});// 启动服务器
server.listen(PORT, () => {console.log(`Server is running on http://localhost:${PORT}`);
});

3.2.3 客户端代码示例

为了让设备能够发送数据并接收实时更新,我们需要在设备端实现Socket.IO客户端。以下是一个简单的客户端示例代码(假设设备使用 Node.js):

// device.js
const io = require('socket.io-client');
const socket = io('http://localhost:3000');// 模拟设备数据
setInterval(() => {const deviceData = {name: '温度传感器',type: '传感器',status: '在线',value: Math.random() * 100 // 随机生成温度值};// 发送数据到服务器socket.emit('data', deviceData);
}, 5000); // 每5秒发送一次数据// 监听服务器广播的数据
socket.on('data', (data) => {console.log('Data received from server:', data);
});

3.2.4 启动设备客户端

在设备端运行上述代码,以便模拟设备向服务器发送数据。你可以在多个终端中运行多个设备客户端,以模拟多个设备同时连接。

node device.js

这将每5秒随机发送一次温度数据到服务器,并在接收到服务器的广播消息时输出信息。

4. 安全性

安全性是物联网系统非常重要的一部分。为了确保系统的安全性,我们可以实现身份验证、加密通信和定期更新。

4.1 身份验证与授权

为确保只有授权设备能够连接到服务器,可以使用 JWT(JSON Web Token)进行身份验证。以下是如何实现基本的 JWT 身份验证。

首先,安装必要的库:

npm install jsonwebtoken bcryptjs

然后,在 server.js 中添加以下代码:

const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');const SECRET_KEY = 'your_secret_key'; // 应该存储在环境变量中// 用户模型(示例)
const UserSchema = new mongoose.Schema({username: String,password: String
});
const User = mongoose.model('User', UserSchema);// 用户注册接口
app.post('/api/register', async (req, res) => {const { username, password } = req.body;const hashedPassword = await bcrypt.hash(password, 10);const user = new User({ username, password: hashedPassword });await user.save();res.status(201).send('User registered');
});// 用户登录接口
app.post('/api/login', async (req, res) => {const { username, password } = req.body;const user = await User.findOne({ username });if (!user || !await bcrypt.compare(password, user.password)) {return res.status(401).send('Invalid credentials');}const token = jwt.sign({ id: user._id }, SECRET_KEY, { expiresIn: '1h' });res.status(200).json({ token });
});// 中间件:验证JWT
const authenticateJWT = (req, res, next) => {const token = req.headers['authorization'];if (token) {jwt.verify(token, SECRET_KEY, (err, user) => {if (err) {return res.sendStatus(403);}req.user = user;next();});} else {res.sendStatus(401);}
};// 保护的设备注册接口
app.post('/api/devices', authenticateJWT, async (req, res) => {const device = new Device(req.body);await device.save();res.status(201).send(device);
});

4.2 加密通信

为了确保数据在传输过程中的安全性,我们将使用 HTTPS。以下是如何设置 HTTPS 的步骤。

首先,您需要 SSL 证书。可以使用自签名证书来进行开发和测试,或者使用 Let's Encrypt 获取免费的证书。

4.2.1 生成自签名证书(开发环境)
# 生成 SSL 证书和密钥
openssl req -nodes -new -x509 -keyout server.key -out server.cert
4.2.2 修改服务器以支持 HTTPS

在 server.js 中,我们将使用HTTPS模块来创建服务器。

const https = require('https');
const fs = require('fs');// 读取证书和密钥
const privateKey = fs.readFileSync('server.key', 'utf8');
const certificate = fs.readFileSync('server.cert', 'utf8');const credentials = { key: privateKey, cert: certificate };// 创建 HTTPS 服务器
const httpsServer = https.createServer(credentials, app);// 启动 HTTPS 服务器
httpsServer.listen(PORT, () => {console.log(`Server is running on https://localhost:${PORT}`);
});

5. 数据分析和可视化

在物联网应用中,数据分析和可视化可以帮助用户理解和利用数据。我们可以使用第三方库或工具来实现数据分析和可视化,以下是一些常用的工具:

  • Grafana:用于监控和可视化时序数据。
  • Chart.js:在前端展示实时数据图表。
  • D3.js:用于复杂的数据可视化。
5.1 集成 Grafana

Grafana 是一个开源的分析和监控平台,可以通过连接到数据库(如 MongoDB)来可视化数据。

  1. 安装 Grafana

    sudo apt install -y grafana
    
  2. 启动 Grafana

    sudo systemctl start grafana-server
    sudo systemctl enable grafana-server
    
  3. 访问 Grafana:在浏览器中访问 http://localhost:3000,默认用户名和密码均为 admin

  4. 添加数据源:在 Grafana 中添加 MongoDB 数据源,并配置它以连接到你的 MongoDB 实例。

  5. 创建仪表盘:通过查询 MongoDB 数据,创建可视化面板,展示传感器数据。

5.2 使用 Chart.js

如果你希望在前端应用中可视化数据,可以使用 Chart.js。以下是一个简单的示例,展示如何使用 Chart.js 来展示实时数据。

在前端应用中,我们将创建一个实时更新的图表,展示从服务器接收到的温度数据。

5.2.1 创建HTML结构

在你的HTML文件中,添加一个<canvas>元素来显示图表。以下是一个完整的HTML示例:

<!DOCTYPE html>
<html lang="zh">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>实时温度数据可视化</title><script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body><h1>实时温度数据</h1><canvas id="myChart" width="400" height="200"></canvas><script src="/socket.io/socket.io.js"></script><script>const socket = io('http://localhost:3000'); // 连接到服务器const ctx = document.getElementById('myChart').getContext('2d');const labels = []; // 存储时间标签const dataPoints = []; // 存储实时数据const myChart = new Chart(ctx, {type: 'line',data: {labels: labels,datasets: [{label: '温度数据',data: dataPoints,borderColor: 'rgba(75, 192, 192, 1)',borderWidth: 1,fill: false}]},options: {scales: {x: {type: 'linear',position: 'bottom'}}}});// 监听服务器发送的数据socket.on('data', (data) => {// 假设数据格式为 { value: 温度值, timestamp: 时间戳 }const timestamp = new Date().toLocaleTimeString();labels.push(timestamp);dataPoints.push(data.value);// 更新图表myChart.update();});</script>
</body>
</html>

5.2.2 图表数据更新

这个示例中,我们使用 Socket.IO 实时接收数据,并将其添加到图表中。我们假设服务器发送的数据的格式如下:

{"value": 25.5 // 温度值
}

在客户端代码中,我们通过监听 socket.on('data', ...) 来接收服务器发送的实时数据,并将数据点和时间标签添加到 Chart.js 图表的数据集中。调用 myChart.update() 方法来更新图表。

6. 事件处理与报警

为了确保系统能够及时处理异常事件并进行报警,我们可以实现一个简单的事件处理系统。

6.1 事件检测

在服务端,我们可以设置一个阈值,并在接收到数据后检查数据是否超出这个阈值。

// 设定温度阈值
const TEMPERATURE_THRESHOLD = 75;// 监听来自设备的数据
socket.on('data', async (data) => {console.log('Received data:', data);// 检查温度是否超出阈值if (data.value > TEMPERATURE_THRESHOLD) {console.log('Warning: Temperature exceeds threshold!', data.value);// 发送报警通知io.emit('alert', { message: 'Temperature exceeds threshold!', value: data.value });}// 存储数据const deviceData = new Device(data);await deviceData.save();// 向所有连接的客户端广播接收到的数据io.emit('data', deviceData);
});
6.2 报警系统

在客户端,我们也可以监听 alert 事件,并根据需要做出响应。

// 监听报警事件
socket.on('alert', (alert) => {alertUser(alert.message, alert.value);
});// 简单的报警通知函数
function alertUser(message, value) {alert(`报警: ${message} 当前温度: ${value}`);
}

7. 接口与集成

为了让第三方系统能够集成到我们的物联网平台,我们需要提供丰富的 API 接口。

7.1 提供 RESTful API

我们已经实现了一些基础的 API 接口,接下来我们将添加获取所有设备、更新设备状态和删除设备的接口。

7.1.1 获取所有设备数据

添加一个 API 接口以获取所有已注册设备的数据。我们将在 server.js 中添加如下代码:

// 获取所有设备数据
app.get('/api/devices', authenticateJWT, async (req, res) => {try {const devices = await Device.find();res.status(200).json(devices);} catch (error) {res.status(500).json({ message: 'Error fetching devices', error });}
});
7.1.2 更新设备状态

添加一个 API 接口以更新特定设备的状态。我们将使用设备的 ID 作为参数:

// 更新设备状态
app.put('/api/devices/:id', authenticateJWT, async (req, res) => {const { id } = req.params;const { status } = req.body;try {const device = await Device.findByIdAndUpdate(id, { status }, { new: true });if (!device) {return res.status(404).json({ message: 'Device not found' });}res.status(200).json(device);} catch (error) {res.status(500).json({ message: 'Error updating device', error });}
});
7.1.3 删除设备

添加一个 API 接口以删除特定设备。我们同样使用设备的 ID 作为参数:

// 删除设备
app.delete('/api/devices/:id', authenticateJWT, async (req, res) => {const { id } = req.params;try {const device = await Device.findByIdAndDelete(id);if (!device) {return res.status(404).json({ message: 'Device not found' });}res.status(204).send(); // 返回 204 No Content} catch (error) {res.status(500).json({ message: 'Error deleting device', error });}
});

8. 日志与监控

为了确保系统的稳定性和安全性,我们需要实现日志记录和系统监控。可以使用 morgan 中间件来记录 HTTP 请求,并使用其他工具来监控系统性能。

8.1 日志记录

首先,安装 morgan

npm install morgan

然后在 server.js 中添加以下代码,以便记录每个请求的信息:

const morgan = require('morgan');// 使用 morgan 记录 HTTP 请求日志
app.use(morgan('combined'));

这将记录所有请求的详细信息,包括请求方法、URL、状态码和请求时间。

8.2 系统监控

对于系统监控,可以使用工具如 Prometheus 和 Grafana 进行监控。通过收集和可视化系统指标(如 CPU 使用率、内存使用量等),您可以更好地理解和管理系统的性能。

# 安装 Prometheus
sudo apt install prometheus

然后配置 Prometheus 以监控您的 Node.js 应用。可以使用 prom-client 库在应用中导出指标。

npm install prom-client

在 server.js 中添加以下代码:

const client = require('prom-client');// 创建一个 Registry 用于保存指标
const register = new client.Registry();// 创建一个 Gauge 指标来监控请求数量
const httpRequestDurationMicroseconds = new client.Histogram({name: 'http_request_duration_seconds',help: 'Duration of HTTP requests in seconds',labelNames: ['method', 'route', 'code'],registers: [register],
});// 中间件记录请求时间
app.use((req, res, next) => {const end = httpRequestDurationMicroseconds.startTimer();res.on('finish', () => {end({ method: req.method, route: req.path, code: res.statusCode });});next();
});// 提供一个端点用于导出指标
app.get('/metrics', async (req, res) => {res.set('Content-Type', register.contentType);res.end(await register.metrics());
});

9. 用户管理

用户管理是物联网系统的重要组成部分,确保只有授权用户可以访问系统的特定功能。我们将实现用户角色和权限管理,并记录用户操作以便审计和跟踪。

9.1 用户角色和权限管理

在我们的物联网系统中,用户可以具有不同的角色(例如,管理员、普通用户),并且每个角色可以拥有不同的权限。我们可以通过在用户模型中添加角色字段来实现这一点。

9.1.1 修改用户模型

首先,修改我们的用户模型以支持角色:

const UserSchema = new mongoose.Schema({username: String,password: String,role: {type: String,enum: ['admin', 'user'],default: 'user'}
});
9.1.2 修改用户注册接口

确保在用户注册时能够指定角色(可选):

// 用户注册接口
app.post('/api/register', async (req, res) => {const { username, password, role } = req.body;const hashedPassword = await bcrypt.hash(password, 10);const user = new User({ username, password: hashedPassword, role });await user.save();res.status(201).send('User registered');
});
9.2 权限控制

我们需要在 API 中实施权限控制,以确保只有特定角色的用户能够访问某些功能。例如,只有管理员可以删除设备。

9.2.1 创建中间件进行权限检查

我们可以创建一个中间件来检查用户的角色:

// 权限检查中间件
const authorizeRoles = (...allowedRoles) => {return (req, res, next) => {const { role } = req.user; // 从请求中获取用户角色if (!allowedRoles.includes(role)) {return res.status(403).json({ message: 'Access forbidden: insufficient rights' });}next();};
};
9.2.2 修改删除设备接口

使用角色检查中间件来保护删除设备的接口:

// 删除设备
app.delete('/api/devices/:id', authenticateJWT, authorizeRoles('admin'), async (req, res) => {const { id } = req.params;try {const device = await Device.findByIdAndDelete(id);if (!device) {return res.status(404).json({ message: 'Device not found' });}res.status(204).send(); // 返回 204 No Content} catch (error) {res.status(500).json({ message: 'Error deleting device', error });}
});

9.3 审计和跟踪

为了记录用户的操作,我们可以在每个敏感操作的 API 接口中添加日志记录。

9.3.1 修改用户注册接口

在用户注册接口中,我们已经记录了日志。以下是完整的用户注册接口代码:

// 用户注册接口
app.post('/api/register', async (req, res) => {const { username, password, role } = req.body;const hashedPassword = await bcrypt.hash(password, 10);const user = new User({ username, password: hashedPassword, role });await user.save();// 记录日志const log = new Log({ userId: user._id, action: `Registered user ${username}` });await log.save();res.status(201).send('User registered');
});
9.3.2 修改用户登录接口

在用户登录接口中,我们可以记录用户的登录操作:

// 用户登录接口
app.post('/api/login', async (req, res) => {const { username, password } = req.body;const user = await User.findOne({ username });if (!user || !await bcrypt.compare(password, user.password)) {return res.status(401).send('Invalid credentials');}const token = jwt.sign({ id: user._id, role: user.role }, SECRET_KEY, { expiresIn: '1h' });// 记录登录日志const log = new Log({ userId: user._id, action: `User ${username} logged in` });await log.save();res.status(200).json({ token });
});
9.3.3 修改更新设备状态接口

在设备状态更新接口中记录日志:

// 更新设备状态
app.put('/api/devices/:id', authenticateJWT, async (req, res) => {const { id } = req.params;const { status } = req.body;try {const device = await Device.findByIdAndUpdate(id, { status }, { new: true });if (!device) {return res.status(404).json({ message: 'Device not found' });}// 记录日志const log = new Log({ userId: req.user.id, action: `Updated device ${id} status to ${status}` });await log.save();res.status(200).json(device);} catch (error) {res.status(500).json({ message: 'Error updating device', error });}
});
9.3.4 修改获取所有设备数据接口

在获取所有设备数据的接口中记录日志:

// 获取所有设备数据
app.get('/api/devices', authenticateJWT, async (req, res) => {try {const devices = await Device.find();// 记录日志const log = new Log({ userId: req.user.id, action: `Fetched all devices` });await log.save();res.status(200).json(devices);} catch (error) {res.status(500).json({ message: 'Error fetching devices', error });}
});

9.4 查看操作日志

为了方便审计和追踪,您可能需要一个接口来查看操作日志。我们可以添加一个新的 API 接口来获取所有日志记录:

// 获取所有日志记录
app.get('/api/logs', authenticateJWT, authorizeRoles('admin'), async (req, res) => {try {const logs = await Log.find().populate('userId', 'username'); // Populate userId to get usernameres.status(200).json(logs);} catch (error) {res.status(500).json({ message: 'Error fetching logs', error });}
});

10. 结论

通过上述步骤,我们已经搭建了一个完整的物联网服务器,涵盖了以下关键模块:

  • 设备管理:实现了设备的注册、更新、删除和查询功能,支持大规模设备的管理。这为物联网应用提供了基础设施,使得各种设备可以被有效地管理和控制。

  • 数据处理与存储:通过使用 MongoDB 等数据库高效存储设备数据,并实现实时数据处理功能,使得系统能够及时响应设备状态变化,支持边缘计算和云端计算的结合。

  • 安全性:使用 JWT 实现身份验证和权限管理,确保只有授权用户和设备能够访问系统,降低了安全隐患。此外,通过 HTTPS 加密通信,保护了数据在传输过程中的安全。

  • 可扩展性与高可用性:设计了可横向扩展的架构,保证随着设备数量的增加,系统能够稳定运行。同时,通过负载均衡和容错机制提高了系统的可用性。

  • 数据分析与可视化:集成了 Grafana 和 Chart.js 等工具,提供了丰富的数据可视化功能,使用户能够实时监控和分析数据,帮助用户做出更好的决策。

  • 事件处理与报警:实现了实时事件检测和报警系统,确保用户能够及时获知异常情况,提高了系统的可靠性。

  • 接口与集成:提供了丰富的 RESTful API 接口,使得第三方系统能够方便地与物联网平台进行集成,增强了系统的互操作性。

  • 日志与监控:通过记录用户操作日志和系统性能指标,提供了审计和监控功能,有助于系统的维护和安全审查。

  • 用户管理:实现了用户角色和权限管理,确保系统的安全性和可控性,并通过日志系统实现了用户操作的审计和跟踪。

10.1 参考资料

在搭建物联网服务器的过程中,可以参考以下资料和文档:

  • Node.js 官方文档
  • MongoDB 官方文档
  • Express.js 官方文档
  • Socket.IO 官方文档
  • JWT 官方文档
  • Grafana 官方文档
  • Chart.js 官方文档

非常感谢您阅读到这里!您的关注和支持是我不断前进的动力。搭建物联网服务器是一个充满挑战的旅程,但通过本指南,希望您能掌握关键步骤,构建出功能强大的物联网平台

——by 极客小张

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

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

相关文章

uniapp+vue微信小程序项目中实现手机号授权登录

效果图: 实现方式: <button open-type="getPhoneNumber" class="btn-normal" @getphonenumber="getPhoneNumber">手机号授权登录</button> open-type 有效值 值说明平台差异说明getPhoneNumber获取用户手机号,可以从@getphone…

LeetCode Hot100 将有序数组转换为二叉搜索树

给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xff0c;请你将其转换为一棵 平衡 二叉搜索树。 示例 1&#xff1a; 输入&#xff1a;nums [-10,-3,0,5,9] 输出&#xff1a;[0,-3,9,-10,null,5] 解释&#xff1a;[0,-10,5,null,-3,null,9] 也将被视为正确…

SpringBoot整合jasypt加密和解密yml配置文件

使用场景 在微服务架构中&#xff0c;配置管理是一个重要的问题。通常&#xff0c;我们会在配置文件中存放一些敏感信息&#xff0c;如数据库连接字符串、API 密钥等。这些敏感信息如果明文存储在配置文件中&#xff0c;存在较大的安全隐患。为了提高安全性&#xff0c;我们需…

Linux安装与配置

下载VMware 首先我们需要下载一个叫VMware的软件&#xff1a; 进入官方下载&#xff0c;地址&#xff1a;https://www.vmware.com/cn/products/workstation-pro/workstation-pro-evaluation.html选择与自己电脑版本适配的VMware版本【 输入许可证密钥 MC60H-DWHD5-H80U9-6V85…

Python | “IndexError: tuple index out of range” 【已解决】

Python | “IndexError: tuple index out of range” 【已解决】 IndexError: tuple index out of range 深度解析与实战指南 在Python编程中&#xff0c;IndexError: tuple index out of range是一个常见的错误&#xff0c;它发生在尝试访问元组&#xff08;或其他可索引的数…

前端canvas——贝塞尔曲线

曲线之美&#xff0c;不在于曲线本身&#xff0c;而在于用的人。 所以就有了这期贝塞尔曲线。 新规矩&#xff0c;先上个GIT。 效果图 开局一张图&#xff0c;代码全靠编。 代码 画骨 先想着怎么画一个心形吧&#xff0c;等你想好了&#xff0c;就知道怎么画了。 首先就还…

iPhone 中阅读器模式是什么?怎么开启该模式?

什么是阅读器模式&#xff1f;这是一个浏览器功能&#xff0c;可以为用户提供简洁、干净的阅读界面。当你在 Safari 浏览器中启用阅读器模式时&#xff0c;网页上的广告、侧边栏和其他不相关的元素将被移除&#xff0c;仅保留主要的文字内容和相关图片。这使得用户可以专注于阅…

前端开发的十字路口,薪的出口会是AI吗?

前言 在数字化转型的浪潮中&#xff0c;前端开发一直扮演着至关重要的角色&#xff0c;它连接着用户与产品之间的桥梁。然而&#xff0c;随着技术的不断进步和社会经济环境的变化&#xff0c;前端开发领域也面临着前所未有的挑战和机遇。 前端开发的困境 前端开发领域的竞争…

Vue3多语言实现

1.首先安装i18n npm install vue-i18n 2.在项目下创建lang目录并创建en.ts,i18n1.ts,zh.ts en.ts export default {message: {home: home,appTitle:aa 3D Smart Measure}, Menus: {Measuer: Measure,},GlueMeasure: {Title: Camera 3D Glue Measure,}} zh.ts export …

android(安卓)最简单明了解释版本控制之MinSdkVersion、CompileSdkVersion、TargetSdkVersion

1、先明白几个概念 &#xff08;1&#xff09;平台版本&#xff08;Android SDK版本号&#xff09; 平台版本也就是我们平时说的安卓8、安卓9、安卓10 &#xff08;2&#xff09;API级别&#xff08;API Level&#xff09; Android 平台提供的框架 API 被称作“API 级别” …

什么是CAN的BUS-OFF,如何恢复BUS-OFF?

CAN作为一款强大的工业总线&#xff0c;其高性能和高可靠性让其应用特别广泛。一个小知识&#xff1a;汽车里面各个模块之间的通讯就是使用CAN来实现的哦。 既然是总线&#xff0c;那当然会有多个设备挂载在CAN上&#xff0c;当一个设备在发送数据的时候&#xff0c;其他设备也…

基于STC8H4K64TL单片机的RTC(即实时时钟)功能调试

基于STC8H4K64TL单片机的RTC(即实时时钟)功能调试 STC8H4K64TL单片机介绍STC8H4K64TL单片机管脚图(48个引脚)STC8H4K64TL单片机串口仿真与串口通信STC8H4K64TL单片机管脚图(32个引脚)STC8H4K64TL单片机管脚图(20个引脚)STC8H系列单片机管脚说明STC8H系列单片机I/O口STC…

大模型不会比大小和单词字母计数?日期计算也是一片混乱

9.9和9.11哪个大&#xff1f;13.8%和13.11%谁大谁小&#xff1f;这两个比大小的问题&#xff0c;前段时间难倒众多大模型&#xff0c;在网上掀起热议。 除此之外&#xff0c;向大模型提问“草莓&#xff08;strawberry&#xff09;这个单词有几个r时”&#xff0c;多家主流大模…

三目操作符

双目操作符有、-、*、/、% 单目操作符有--、、、- 三目操作符有表达式1&#xff1f;表达式2&#xff1a;表达式3 如果表达式1为真则表达式2计算否则表达式3计算&#xff0c;计算结果为整个表达式的结果 #include<stdio.h> int main() {int a 0;int b 0;scanf(&quo…

Doris-计算特性

1 全新优化器 1.1 如何开启1.2 统计信息 1.2.1 使用ANALYZE语句手动收集1.2.1 自动收集1.2.3 作业管理1.3 会话变量及配置项调优参数2 Join相关 2.1 支持的Join算子2.2 支持的shuffle方式 2.2.1 Broadcast Join2.2.2 Shuffle Join2.2.3 Bucket Shuffle Join 2.2.3.1 原理2.2.3.…

PHP反序列化漏洞从入门到深入8k图文介绍,以及phar伪协议的利用

文章参考&#xff1a;w肝了两天&#xff01;PHP反序列化漏洞从入门到深入8k图文介绍&#xff0c;以及phar伪协议的利用 前言 本文内容主要分为三个部分&#xff1a;原理详解、漏洞练习和防御方法。这是一篇针对PHP反序列化入门者的手把手教学文章&#xff0c;特别适合刚接触PH…

Windows搭建我的世界MC服务器 【Minecraft外网联机教程】

目录 ⛳️推荐 1. 搭建我的世界服务器 1.1 服务器安装java环境 1.2 配置服务端 1.3 创建我的世界服务器 2. 局域网联机测试 3. 安装cpolar内网穿透 4. 公网联机Minecraft 5. 配置固定远程联机端口地址 ⛳️推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通…

新手转行AI运营岗位,轻松实现月入15K+

近年来人工智能大爆发&#xff0c;各种AI产品层出不穷&#xff0c;市场也出现了一批高薪AI运营类岗位 不需要技术背景、门槛低&#xff0c;即便是新手&#xff0c;也有机会拿下offer。如果你计划今年跳槽或转行运营&#xff0c;这5个岗位不妨试试&#xff08;结尾附国内AI公司清…

科普文:万字梳理高性能 Kafka快的8个原因

概叙 科普文&#xff1a;万字详解Kafka基本原理和应用-CSDN博客 科普文&#xff1a;万字梳理31个Kafka问题-CSDN博客 我们都知道 Kafka 是基于磁盘进行存储的&#xff0c;但 Kafka 官方又称其具有高性能、高吞吐、低延时的特点&#xff0c;其吞吐量动辄几十上百万。 在座的…

【深度学习】kaggle使用

https://blog.csdn.net/2301_78630677/article/details/133834096 https://blog.csdn.net/xiaojia1001/article/details/139467176 https://www.kaggle.com/ 使用要挂代理&#xff0c;要不然可能无法注册 绑定手机号之后才能使用GPU 每周30h免费GPU使用时长 上传数据集 Ad…