WebSocket 实时通信全攻略:从原理到实践
"实时通信是现代 Web 应用的核心能力。WebSocket 让浏览器和服务器之间的双向通信变得简单高效。"
一、什么是 WebSocket?
WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。与传统的 HTTP 请求-响应模式不同,WebSocket 允许服务器主动向客户端推送数据,非常适合实时应用场景。
1.1 WebSocket 与 HTTP 的区别
HTTP 协议:客户端发起请求,服务器响应,一次请求一次响应,无法主动推送。
WebSocket 协议:建立连接后,客户端和服务器都可以随时发送消息,实现双向实时通信。
1.2 WebSocket 的优势
- 实时性强:服务器可以主动推送,无需轮询
- 开销小:建立连接后,数据帧头部仅 2-10 字节
- 双向通信:客户端和服务器可同时收发消息
- 跨域支持:支持跨域连接
二、WebSocket 应用场景
WebSocket 在以下场景中有着广泛的应用:
- 即时聊天:微信网页版、在线客服系统
- 实时数据:股票行情、体育比分直播
- 协作办公:在线文档、白板协作
- 在线游戏:多人联机、实时对战
- 物联网:设备监控、智能家居
三、WebSocket 基础实战
3.1 创建 WebSocket 连接
在浏览器中创建 WebSocket 连接非常简单:
// 创建 WebSocket 连接
const ws = new WebSocket('wss://example.com/ws');
// 连接成功
ws.onopen = function(event) {
console.log('WebSocket 连接已建立');
ws.send('Hello, Server!');
};
// 接收消息
ws.onmessage = function(event) {
console.log('收到消息:', event.data);
};
// 连接关闭
ws.onclose = function(event) {
console.log('WebSocket 连接已关闭');
};
// 错误处理
ws.onerror = function(error) {
console.error('WebSocket 错误:', error);
};
3.2 发送和接收消息
WebSocket 支持发送文本和二进制数据:
// 发送文本消息
ws.send('这是一条文本消息');
// 发送 JSON 数据
const data = {
type: 'chat',
content: '你好!',
timestamp: Date.now()
};
ws.send(JSON.stringify(data));
// 发送二进制数据
const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);
view.setInt32(0, 1234);
ws.send(buffer);
四、Node.js 服务端实现
4.1 使用 ws 库搭建服务器
const WebSocket = require('ws');
// 创建 WebSocket 服务器
const wss = new WebSocket.Server({ port: 8080 });
// 存储所有连接的客户端
const clients = new Set();
wss.on('connection', function(ws, req) {
console.log('新客户端连接');
clients.add(ws);
// 接收消息
ws.on('message', function(message) {
console.log('收到消息:', message.toString());
// 广播给所有客户端
clients.forEach(client => {
if (client.readyState === WebSocket.OPEN) {
client.send(message.toString());
}
});
});
// 连接关闭
ws.on('close', function() {
console.log('客户端断开');
clients.delete(ws);
});
});
console.log('WebSocket 服务器运行在 ws://localhost:8080');
4.2 结合 Express 使用
const express = require('express');
const http = require('http');
const WebSocket = require('ws');
const app = express();
const server = http.createServer(app);
const wss = new WebSocket.Server({ server });
// 静态文件
app.use(express.static('public'));
// HTTP 路由
app.get('/api/status', (req, res) => {
res.json({ status: 'ok', clients: wss.clients.size });
});
// WebSocket 连接
wss.on('connection', (ws) => {
ws.on('message', (message) => {
// 广播消息
wss.clients.forEach(client => {
if (client.readyState === WebSocket.OPEN) {
client.send(message.toString());
}
});
});
});
server.listen(3000, () => {
console.log('服务器运行在 http://localhost:3000');
});
五、心跳检测与重连机制
5.1 客户端心跳检测
class WebSocketClient {
constructor(url) {
this.url = url;
this.ws = null;
this.heartbeatTimer = null;
this.reconnectTimer = null;
this.connect();
}
connect() {
this.ws = new WebSocket(this.url);
this.ws.onopen = () => {
console.log('连接成功');
this.startHeartbeat();
};
this.ws.onmessage = (event) => {
if (event.data === 'pong') {
// 心跳响应
return;
}
this.onMessage(event.data);
};
this.ws.onclose = () => {
this.stopHeartbeat();
this.reconnect();
};
}
startHeartbeat() {
this.heartbeatTimer = setInterval(() => {
if (this.ws.readyState === WebSocket.OPEN) {
this.ws.send('ping');
}
}, 30000);
}
stopHeartbeat() {
if (this.heartbeatTimer) {
clearInterval(this.heartbeatTimer);
}
}
reconnect() {
this.reconnectTimer = setTimeout(() => {
console.log('尝试重新连接...');
this.connect();
}, 5000);
}
onMessage(data) {
console.log('收到消息:', data);
}
}
六、实际案例:简易聊天室
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>聊天室</title>
<style>
#messages { height: 400px; overflow-y: auto; border: 1px solid #ccc; }
.message { padding: 10px; border-bottom: 1px solid #eee; }
</style>
</head>
<body>
<div id="messages"></div>
<input type="text" id="input" placeholder="输入消息...">
<button onclick="send()">发送</button>
<script>
const ws = new WebSocket('wss://your-server.com/chat');
const messages = document.getElementById('messages');
const input = document.getElementById('input');
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
messages.innerHTML += `<div class="message">
<strong>${data.user}:</strong> ${data.message}
</div>`;
messages.scrollTop = messages.scrollHeight;
};
function send() {
const message = input.value.trim();
if (message) {
ws.send(JSON.stringify({ type: 'chat', message }));
input.value = '';
}
}
input.addEventListener('keypress', (e) => {
if (e.key === 'Enter') send();
});
</script>
</body>
</html>
七、安全注意事项
在使用 WebSocket 时,需要注意以下安全问题:
- 使用 wss://:生产环境必须使用加密连接
- 身份验证:建立连接时验证用户身份
- 消息验证:验证接收消息的格式和内容
- 频率限制:限制消息发送频率,防止滥用
- 连接数限制:限制单个用户的连接数
总结
WebSocket 为实时通信提供了简洁高效的解决方案。从简单的聊天应用到复杂的协作系统,WebSocket 都是现代 Web 开发的重要工具。掌握 WebSocket,让你的应用具备实时能力。
相关推荐:
Node.js 实战教程 | Express 框架指南 | Socket.IO 入门
本文链接:https://www.kkkliao.cn/?id=769 转载需授权!
版权声明:本文由廖万里的博客发布,如需转载请注明出处。



手机流量卡
免费领卡
号卡合伙人
产品服务
关于本站
