WebSocket:实时双向通信技术详解与实战示例优化指南
目录
1.WebSocket 基础
2.WebSocket 的工作原理
连接过程
3.WebSocket 在前端的实现
4.WebSocket 在后端的实现
使用 Node.js 搭建 WebSocket 服务器
5.WebSocket 在嵌入式系统中的应用
嵌入式 WebSocket 客户端(ESP32)
6.WebSocket vs. MQTT(IoT 选择)
7.小结
8.WebSocket示例:实时推送传感器数据(如温度、湿度)
(1)WebSocket 服务器端(示例)
Node.js(WebSocket 服务器)
(2)React 前端(接收 WebSocket 传感器数据并展示)
React 组件
(3)WebSocket 断线重连
(4)结合图表(实时可视化数据)
安装 Recharts
更新 React 组件(添加折线图)
效果
(5)WebSocket 在 IoT 场景中的应用
(6)总结
WebSocket 是一种全双工通信协议,适用于需要实时数据交互的应用,如聊天应用、股票行情、在线游戏、IoT 设备控制等。它相比传统的 HTTP 请求具有更低的延迟和更高的效率,适用于嵌入式和 Web 开发。
1.WebSocket 基础
特点:
-
全双工通信:客户端和服务器可以同时发送和接收数据,而不像 HTTP 需要请求-响应模式。
-
减少带宽消耗:相比 HTTP 轮询,WebSocket 只在建立连接时进行一次 HTTP 请求,之后使用单个 TCP 连接进行数据传输,无需每次发送数据都重新建立连接。
-
低延迟:适合实时应用,如物联网(IoT)、在线协作、股票交易等。
2.WebSocket 的工作原理
WebSocket 采用 ws:// 或 wss://(安全版,基于 TLS 加密) 协议,建立握手后,客户端和服务器可以随时通信。
连接过程
(1)客户端发起 WebSocket 连接(使用 ws://
或 wss://
)。
(2)服务器响应并完成 WebSocket 握手(HTTP 101 Switching Protocols)。
(3)建立 WebSocket 连接后,双向通信可以随时进行。
(4)任何一方都可以关闭连接。
3.WebSocket 在前端的实现
前端 JavaScript 使用 WebSocket
API 进行通信:
const socket = new WebSocket("ws://example.com/socket");
// 监听连接成功
socket.onopen = function () {
console.log("WebSocket 连接已建立");
socket.send("Hello Server!"); // 发送消息
};
// 监听服务器消息
socket.onmessage = function (event) {
console.log("收到消息:", event.data);
};
// 监听连接关闭
socket.onclose = function () {
console.log("WebSocket 连接已关闭");
};
// 监听错误
socket.onerror = function (error) {
console.error("WebSocket 错误:", error);
};
4.WebSocket 在后端的实现
使用 Node.js 搭建 WebSocket 服务器
const WebSocket = require('ws');
const server = new WebSocket.Server({ port: 8080 });
server.on('connection', (ws) => {
console.log('客户端连接成功');
ws.on('message', (message) => {
console.log('收到客户端消息:', message);
ws.send('服务器收到消息: ' + message);
});
ws.on('close', () => {
console.log('客户端断开连接');
});
});
console.log('WebSocket 服务器运行在 ws://localhost:8080');
5.WebSocket 在嵌入式系统中的应用
在嵌入式开发中,WebSocket 可以用于:
-
IoT 设备远程控制(如智能锁、智能灯泡)
-
实时传感器数据采集(温度、湿度、GPS 位置)
-
工业设备状态监测
嵌入式 WebSocket 客户端(ESP32)
使用 ESP32(Arduino 代码)连接 WebSocket 服务器:
#include <WiFi.h>
#include <WebSocketsClient.h>
const char* ssid = "你的WiFi名称";
const char* password = "你的WiFi密码";
WebSocketsClient webSocket;
void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) {
switch (type) {
case WStype_CONNECTED:
Serial.println("连接到 WebSocket 服务器");
webSocket.sendTXT("Hello Server!");
break;
case WStype_TEXT:
Serial.printf("收到消息: %s\n", payload);
break;
case WStype_DISCONNECTED:
Serial.println("WebSocket 断开连接");
break;
}
}
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("正在连接WiFi...");
}
Serial.println("WiFi 连接成功");
webSocket.begin("example.com", 8080, "/");
webSocket.onEvent(webSocketEvent);
}
void loop() {
webSocket.loop();
}
6.WebSocket vs. MQTT(IoT 选择)
特性 | WebSocket | MQTT |
协议类型 | 基于 TCP | 基于 TCP(支持 QoS 机制) |
通信模式 | 客户端-服务器 | 发布-订阅模式(多设备通信) |
功耗 | 较高(长连接) | 低功耗(适用于 IoT 设备) |
数据格式 | 任何格式(JSON、二进制等) | 轻量级(小型二进制数据) |
应用场景 | Web 应用、实时聊天、游戏 | 物联网、远程传感器数据 |
对于物联网(IoT)设备,如果是简单的点对点通信,可以使用 WebSocket,如果需要多个设备之间数据共享,推荐使用 MQTT。
7.小结
-
WebSocket 适用于实时数据交互,比 HTTP 更高效。
-
在前端可以直接使用
WebSocket
API,后端可以用 Node.js 或 Python 搭建服务器。 -
在嵌入式开发中,WebSocket 可用于 IoT 设备远程控制,如 ESP32 实现 WebSocket 客户端。
-
如果是物联网场景,MQTT 可能是更好的选择。
8.WebSocket示例:实时推送传感器数据(如温度、湿度)
在前端通过 WebSocket 实时推送并展示 传感器数据(温度、湿度等),可以按照以下步骤进行:
(1)WebSocket 服务器端(示例)
假设有一个 WebSocket 服务器,每隔 2 秒向前端推送 温度和湿度 数据:
Node.js(WebSocket 服务器)
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', ws => {
console.log('客户端已连接');
// 模拟传感器数据,每2秒推送一次
setInterval(() => {
const temperature = (20 + Math.random() * 5).toFixed(2); // 模拟温度数据 (20~25°C)
const humidity = (50 + Math.random() * 10).toFixed(2); // 模拟湿度数据 (50~60%)
ws.send(JSON.stringify({ temperature, humidity, timestamp: new Date().toISOString() }));
}, 2000);
ws.on('close', () => console.log('客户端断开连接'));
});
-
监听客户端连接 (
connection
事件) -
使用
setInterval
定时推送 传感器数据 -
数据格式为 JSON,包含
temperature
(温度)、humidity
(湿度)和timestamp
(时间戳)
(2)React 前端(接收 WebSocket 传感器数据并展示)
前端使用 WebSocket 连接服务器,并在 UI 上实时更新传感器数据。
React 组件
import { useState, useEffect } from "react";
const SensorData = () => {
const [sensorData, setSensorData] = useState({ temperature: 0, humidity: 0, timestamp: "" });
useEffect(() => {
const socket = new WebSocket("ws://localhost:8080");
socket.onopen = () => console.log("WebSocket 连接成功");
socket.onmessage = (event) => {
const data = JSON.parse(event.data);
setSensorData(data);
};
socket.onerror = (error) => console.error("WebSocket 错误:", error);
socket.onclose = () => console.log("WebSocket 连接关闭");
return () => socket.close(); // 组件卸载时关闭连接
}, []);
return (
<div style={{ padding: "20px", fontSize: "18px", textAlign: "center" }}>
<h2>实时传感器数据</h2>
<p>🌡 温度: {sensorData.temperature} °C</p>
<p>💧 湿度: {sensorData.humidity} %</p>
<p>📅 更新时间: {new Date(sensorData.timestamp).toLocaleTimeString()}</p>
</div>
);
};
export default SensorData;
(3)WebSocket 断线重连
由于网络波动,WebSocket 可能会断开连接,可以增加自动重连机制:
let socket;
let reconnectInterval = 3000; // 3 秒后尝试重连
function connectWebSocket(setSensorData) {
socket = new WebSocket("ws://localhost:8080");
socket.onopen = () => console.log("WebSocket 连接成功");
socket.onmessage = (event) => {
const data = JSON.parse(event.data);
setSensorData(data);
};
socket.onerror = (error) => console.error("WebSocket 发生错误:", error);
socket.onclose = () => {
console.warn("WebSocket 断开连接,尝试重连...");
setTimeout(() => connectWebSocket(setSensorData), reconnectInterval);
};
}
// 在 React 中使用
useEffect(() => {
connectWebSocket(setSensorData);
return () => socket && socket.close();
}, []);
这样即使服务器重启或网络异常,WebSocket 也会自动重连。
(4)结合图表(实时可视化数据)
如果想要在 React 前端 用图表展示温度/湿度变化趋势,可以使用 Recharts 库:
安装 Recharts
npm install recharts
更新 React 组件(添加折线图)
import { useState, useEffect } from "react";
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from "recharts";
const SensorChart = () => {
const [sensorData, setSensorData] = useState([]);
useEffect(() => {
const socket = new WebSocket("ws://localhost:8080");
socket.onmessage = (event) => {
const data = JSON.parse(event.data);
setSensorData(prevData => [...prevData.slice(-20), { ...data, time: new Date(data.timestamp).toLocaleTimeString() }]);
};
return () => socket.close();
}, []);
return (
<div style={{ width: "100%", height: 300 }}>
<h2 style={{ textAlign: "center" }}>实时传感器数据</h2>
<ResponsiveContainer width="100%" height="100%">
<LineChart data={sensorData}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="time" />
<YAxis />
<Tooltip />
<Legend />
<Line type="monotone" dataKey="temperature" stroke="#ff7300" name="温度 (°C)" />
<Line type="monotone" dataKey="humidity" stroke="#0088FE" name="湿度 (%)" />
</LineChart>
</ResponsiveContainer>
</div>
);
};
export default SensorChart;
效果
-
折线图展示最近 20 次传感器数据变化。
-
X 轴 显示时间,Y 轴 显示温度/湿度。
(5)WebSocket 在 IoT 场景中的应用
在 物联网(IoT) 设备中,可以使用 WebSocket 来:
-
让智能锁、空气净化器、环境监测设备 实时上传数据。
-
让前端 控制 设备状态(例如开/关控制)。
-
与 MQTT 结合(后端用 MQTT 连接 IoT 设备,前端用 WebSocket 获取数据)。
例如,智能锁实时状态监控:
const socket = new WebSocket("ws://iot.example.com/smartlock");
socket.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log(
门锁状态: ${data.locked ? "已上锁" : "已解锁"}
);
};
// 远程解锁
function unlockDoor() {
socket.send(JSON.stringify({ action: "unlock" }));
}
// 远程上锁
function lockDoor() {
socket.send(JSON.stringify({ action: "lock" }));
}
(6)总结
1)WebSocket 适用于实时数据推送,如 温湿度传感器 数据。
2)React 前端可以接收 WebSocket 数据,并实时展示传感器状态。
3)结合图表库(Recharts),可以可视化传感器数据变化趋势。
4)支持自动重连,防止 WebSocket 断开。
5)适用于 IoT 设备,如智能家居、工业传感器、环境监测。
扩展阅读:
MQTT 实战手册:从初学者到高级开发者的进阶之路 | MQTT 实战手册:从初学者到高级开发者的进阶之路-CSDN博客 |
MQTT开发者指南:15个实战问题全解析 | MQTT开发者指南:15个实战问题全解析-CSDN博客 |
WebSocket:实时双向通信技术详解与实战示例优化指南 | https://blog.csdn.net/moton2017/article/details/146475710 |
ESP32 智能锁双协议联动:WebSocket + MQTT 远程控制与状态同步详解 | https://blog.csdn.net/moton2017/article/details/146478480 |