WebSocket

WebSocket提供全双工通信通道,允许服务器主动向客户端推送数据,适用于实时应用。

WebSocket优势

实时通信

服务器可主动推送数据到客户端

低延迟

持久连接,无需重复建立连接

双向通信

客户端和服务器可随时互相发送数据

高效传输

相比HTTP请求,开销更小

协议对比

协议 方向 实时性 复杂度 适用场景
SSE 单向(服务器→客户端) 实时通知、股票价格、日志流
WebSocket 双向 极高 聊天应用、在线游戏、协作工具
Ajax轮询 双向 简单数据更新、兼容性要求高
长轮询 双向 中等 中等 实时应用、但需要兼容低版本浏览器

连接握手过程

WebSocket连接通过HTTP协议进行握手,然后升级为WebSocket协议:

// 客户端请求 GET /ws HTTP/1.1 Host: example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== Sec-WebSocket-Version: 13 // 服务器响应 HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

实现示例

// WebSocket客户端示例 class WebSocketClient { constructor(url) { this.url = url; this.ws = null; this.connect(); } connect() { this.ws = new WebSocket(this.url); this.ws.onopen = event => { console.log('WebSocket连接已建立'); // 发送认证信息 this.send({type: 'auth', token: localStorage.getItem('token')}); }; this.ws.onmessage = event => { const data = JSON.parse(event.data); this.handleMessage(data); }; this.ws.onclose = event => { console.log('WebSocket连接已关闭'); // 尝试重连 setTimeout(() => this.connect(), 5000); }; this.ws.onerror = error => { console.error('WebSocket错误:', error); }; } send(data) { if (this.ws.readyState === WebSocket.OPEN) { this.ws.send(JSON.stringify(data)); } } handleMessage(data) { switch (data.type) { case 'message': // 处理消息 console.log('收到消息:', data.content); break; case 'notification': // 处理通知 showNotification(data.message); break; case 'userUpdate': // 处理用户更新 updateUserInterface(data.user); break; default: console.warn('未知消息类型:', data.type); } } } // 使用示例 const client = new WebSocketClient('ws://localhost:8080/ws'); // 发送消息 client.send({type: 'message', content: 'Hello, world!'}); // 服务器端实现示例 (Node.js/ws) const WebSocket = require('ws'); const wss = new WebSocket.Server({ port: 8080 }); wss.on('connection', (ws) => { console.log('新客户端连接'); ws.on('message', (message) => { const data = JSON.parse(message); // 处理不同类型的消息 switch (data.type) { case 'message': // 广播消息给所有连接的客户端 wss.clients.forEach((client) => { if (client.readyState === WebSocket.OPEN) { client.send(JSON.stringify({ type: 'message', content: data.content, timestamp: Date.now() })); } }); break; case 'auth': // 处理认证 if (validateToken(data.token)) { ws.authenticated = true; ws.send(JSON.stringify({type: 'authSuccess'})); } else { ws.send(JSON.stringify({type: 'authFailed'})); ws.close(); } break; default: console.warn('未知消息类型:', data.type); } }); ws.on('close', () => { console.log('客户端断开连接'); }); ws.on('error', (error) => { console.error('WebSocket错误:', error); }); });

使用场景

实时聊天

即时通讯、在线客服等

多人协作

文档协同编辑、白板协作等

在线游戏

多人游戏、实时对战等

实时监控

系统监控、数据可视化等

安全考虑

认证与授权

在连接建立后验证用户身份,确保只有授权用户能进行通信

跨站WebSocket攻击

验证Origin头,防止恶意网站利用用户身份建立WebSocket连接

消息验证

验证客户端发送的消息格式和内容,防止注入攻击

连接限制

限制单个IP的连接数,防止WebSocket洪水攻击

最佳实践

  • 实现心跳机制检测连接状态
  • 处理连接断开和重连逻辑
  • 使用二进制数据传输提高效率
  • 实现消息确认和重发机制
  • 考虑使用WebSocket库如Socket.io提供额外功能
  • 使用WSS(WebSocket Secure)加密传输数据
  • 对传输的数据进行适当的序列化和验证
← Backend Graphql Backend Sse →