1070 字
5 分钟
WebSocket 与实时通信

WebSocket 与实时通信#

概述#

WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议,支持服务器主动向客户端推送数据,是实现实时通信的关键技术。

WebSocket 协议#

1. 协议特点#

  • 全双工通信:客户端和服务器可以同时发送数据
  • 低延迟:建立连接后无需重复握手
  • 持久连接:一次握手,长期通信
  • 跨域支持:支持跨域通信

2. 握手过程#

客户端 → 服务器:
GET /chat HTTP/1.1
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=

3. 数据帧格式#

  • FIN:消息结束标志
  • Opcode:操作码(文本/二进制/关闭等)
  • Mask:掩码标志
  • Payload length:数据长度
  • Masking-key:掩码密钥
  • Payload data:实际数据

前端实现#

1. 原生 WebSocket API#

// 创建 WebSocket 连接
const socket = new WebSocket('wss://example.com/chat');

// 连接打开
socket.onopen = function(event) {
    console.log('连接已建立');
    socket.send('Hello Server!');
};

// 接收消息
socket.onmessage = function(event) {
    console.log('收到消息:', event.data);
};

// 连接关闭
socket.onclose = function(event) {
    console.log('连接关闭:', event.code, event.reason);
};

// 错误处理
socket.onerror = function(error) {
    console.error('WebSocket 错误:', error);
};

2. 心跳机制#

// 保持连接活跃
let heartbeatInterval;

function startHeartbeat() {
    heartbeatInterval = setInterval(() => {
        if (socket.readyState === WebSocket.OPEN) {
            socket.send(JSON.stringify({ type: 'heartbeat' }));
        }
    }, 30000); // 30秒一次
}

function stopHeartbeat() {
    clearInterval(heartbeatInterval);
}

3. 重连机制#

class WebSocketClient {
    constructor(url, options = {}) {
        this.url = url;
        this.reconnectAttempts = 0;
        this.maxReconnectAttempts = options.maxReconnectAttempts || 5;
        this.reconnectDelay = options.reconnectDelay || 1000;
        this.connect();
    }

    connect() {
        this.socket = new WebSocket(this.url);
        
        this.socket.onopen = () => {
            this.reconnectAttempts = 0;
            console.log('WebSocket 连接成功');
        };

        this.socket.onclose = (event) => {
            console.log('连接关闭,尝试重连...');
            this.reconnect();
        };
    }

    reconnect() {
        if (this.reconnectAttempts >= this.maxReconnectAttempts) {
            console.error('达到最大重连次数');
            return;
        }

        this.reconnectAttempts++;
        const delay = this.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1);
        
        setTimeout(() => {
            console.log(`第 ${this.reconnectAttempts} 次重连尝试`);
            this.connect();
        }, Math.min(delay, 30000)); // 最大延迟30秒
    }
}

服务器端实现#

1. Node.js 示例(使用 ws 库)#

const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });

wss.on('connection', function connection(ws) {
    console.log('新客户端连接');
    
    // 发送欢迎消息
    ws.send(JSON.stringify({ type: 'welcome', message: '连接成功' }));
    
    // 接收客户端消息
    ws.on('message', function incoming(message) {
        console.log('收到消息:', message);
        
        // 广播给所有客户端
        wss.clients.forEach(function each(client) {
            if (client.readyState === WebSocket.OPEN) {
                client.send(message);
            }
        });
    });
    
    // 连接关闭
    ws.on('close', function close() {
        console.log('客户端断开连接');
    });
});

2. 消息格式设计#

// 建议的消息格式
const messageTypes = {
    TEXT: 'text',           // 文本消息
    IMAGE: 'image',         // 图片消息
    FILE: 'file',           // 文件消息
    SYSTEM: 'system',       // 系统消息
    HEARTBEAT: 'heartbeat', // 心跳
    ERROR: 'error'          // 错误消息
};

// 消息结构
const message = {
    id: 'msg_123456',       // 消息ID
    type: messageTypes.TEXT,
    sender: 'user_123',     // 发送者ID
    receiver: 'user_456',   // 接收者ID(或房间ID)
    content: 'Hello World', // 消息内容
    timestamp: Date.now(),  // 时间戳
    meta: {                 // 元数据
        read: false,
        delivered: false
    }
};

应用场景#

1. 实时聊天#

  • 一对一私聊
  • 群组聊天
  • 客服系统

2. 实时数据展示#

  • 股票行情
  • 监控仪表盘
  • 实时排行榜

3. 协作工具#

  • 协同编辑
  • 远程白板
  • 代码协作

4. 游戏应用#

  • 多人在线游戏
  • 实时对战
  • 游戏状态同步

性能优化#

1. 连接管理#

  • 合理设置连接超时
  • 实现连接池
  • 负载均衡

2. 消息优化#

  • 压缩消息数据
  • 批量发送小消息
  • 使用二进制格式

3. 资源管理#

  • 及时关闭无用连接
  • 监控内存使用
  • 防止内存泄漏

安全考虑#

1. 认证授权#

// 连接时验证 token
wss.on('connection', function connection(ws, request) {
    const token = request.headers['sec-websocket-protocol'];
    if (!validateToken(token)) {
        ws.close(1008, '未授权');
        return;
    }
    // 验证通过,继续处理
});

2. 数据验证#

  • 验证消息格式
  • 防止 XSS 攻击
  • 限制消息大小

3. 速率限制#

  • 限制连接频率
  • 限制消息发送频率
  • 防止 DDoS 攻击

替代方案#

1. Server-Sent Events (SSE)#

  • 服务器到客户端的单向通信
  • 基于 HTTP,兼容性好
  • 适合实时通知场景

2. Long Polling#

  • 兼容性最好
  • 实现简单
  • 延迟较高

3. WebRTC#

  • 点对点通信
  • 低延迟
  • 适合音视频通信

总结#

WebSocket 是实现实时通信的核心技术,在现代 Web 应用中广泛应用。正确使用 WebSocket 需要考虑连接管理、消息格式、性能优化和安全防护等多个方面。


创建时间:2026-03-12 分类:前端网络 标签:WebSocket, 实时通信, 网络协议, 前端开发

WebSocket 与实时通信
https://ameng404.com/posts/network/websocket与实时通信/
作者
Ameng
发布于
2026-03-12
许可协议
CC BY-NC-SA 4.0