pin_drop当前位置:知识文库 ❯ 图文

HTML5 API:HTML5 WebSocket - 完整教程与代码示例

一、教程简介

WebSocket 是 HTML5 提供的一种在单个 TCP 连接上进行全双工通信的协议,使得浏览器和服务器之间可以建立持久化的双向通信通道。与传统的 HTTP 请求-响应模式不同,WebSocket 连接建立后,客户端和服务器可以随时向对方发送数据,无需重复建立连接。WebSocket 广泛应用于即时聊天、实时协作、在线游戏、股票行情、IoT 设备监控等需要低延迟双向通信的场景。


二、核心概念

WebSocket 与 HTTP 对比

特性 HTTP WebSocket
通信模式 请求-响应 全双工
连接生命周期 短连接(HTTP/1.1 可复用) 持久连接
数据格式 文本 文本和二进制
开销 每次请求带完整头部 握手后开销极小
服务器推送 需轮询/SSE 原生支持
协议 http/https ws/wss

连接生命周期

代码示例

客户端                              服务器
  │                                   │
  │  ─── HTTP Upgrade 请求 ────────→  │  握手阶段
  │  ←─── 101 Switching Protocols ──  │
  │                                   │
  │  ←────── 数据帧 ──────────────→  │  通信阶段
  │  ←────── 数据帧 ──────────────→  │  (双向自由发送)
  │  ←────── 数据帧 ──────────────→  │
  │                                   │
  │  ──── Close 帧 ───────────────→  │  关闭阶段
  │  ←──── Close 帧 ───────────────  │
  │                                   │

WebSocket API

代码示例

const ws = new WebSocket(url, protocols);
属性/方法/事件 说明
readyState 连接状态
CONNECTING (0) 正在连接
OPEN (1) 连接已建立
CLOSING (2) 正在关闭
CLOSED (3) 已关闭
bufferedAmount 未发送的数据队列大小
binaryType 二进制数据类型(blob/arraybuffer)
onopen 连接打开事件
onmessage 接收消息事件
onerror 错误事件
onclose 连接关闭事件
send(data) 发送数据
close(code, reason) 关闭连接

关闭代码

代码 说明
1000 正常关闭
1001 端点离开
1002 协议错误
1003 不支持的数据类型
1005 无状态码
1006 异常关闭
1007 无效的载荷数据
1008 策略违规
1009 消息过大
1010 需要扩展
1011 内部错误
3000-3999 自定义(库/框架使用)
4000-4999 自定义(应用使用)

三、语法与用法

创建连接

代码示例

// 基本连接
const ws = new WebSocket('ws://localhost:8080');

// 安全连接
const wss = new WebSocket('wss://example.com/ws');

// 指定子协议
const ws = new WebSocket('wss://example.com/ws', ['chat', 'superchat']);

发送与接收

代码示例

// 发送文本
ws.send('Hello Server');

// 发送 JSON
ws.send(JSON.stringify({ type: 'chat', message: '你好' }));

// 发送二进制数据
const buffer = new ArrayBuffer(4);
ws.send(buffer);

// 发送 Blob
ws.send(new Blob(['binary data'], { type: 'application/octet-stream' }));

// 接收消息
ws.onmessage = function(e) {
    if (typeof e.data === 'string') {
        console.log('文本消息:', e.data);
    } else if (e.data instanceof Blob) {
        console.log('Blob 数据:', e.data);
    } else if (e.data instanceof ArrayBuffer) {
        console.log('ArrayBuffer:', e.data);
    }
};

连接管理

代码示例

ws.onopen = function() {
    console.log('连接已建立');
    ws.send('连接成功!');
};

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

ws.onerror = function(e) {
    console.error('WebSocket 错误');
};

ws.close(1000, '正常关闭');

四、代码示例

示例一:WebSocket 聊天室(模拟)

提示:完整代码示例请参考源文件中的 HTML 实现,包含聊天界面、消息发送、模拟服务器响应等功能。

示例二:WebSocket 连接状态管理与心跳检测

提示:完整代码示例请参考源文件中的连接管理实现,包含心跳检测、断线重连、状态监控等功能。


五、浏览器兼容性

浏览器 支持版本 备注
Chrome 4+ 完整支持
Firefox 4+ 完整支持
Safari 5+ 完整支持
Edge 12+ 完整支持
Opera 10.7+ 完整支持
IE 10+ 部分支持
iOS Safari 4.2+ 完整支持
Android 4.4+ 完整支持

六、注意事项与最佳实践

1. 心跳机制

代码示例

// 心跳保活,检测连接是否存活
class WebSocketWithHeartbeat {
    constructor(url) {
        this.url = url;
        this.ws = null;
        this.heartbeatInterval = 30000;
        this.heartbeatTimer = null;
        this.reconnectAttempts = 0;
        this.maxReconnectAttempts = 5;
    }

    connect() {
        this.ws = new WebSocket(this.url);

        this.ws.onopen = () => {
            this.reconnectAttempts = 0;
            this.startHeartbeat();
        };

        this.ws.onclose = () => {
            this.stopHeartbeat();
            this.attemptReconnect();
        };

        this.ws.onerror = () => {
            this.stopHeartbeat();
        };

        this.ws.onmessage = (e) => {
            if (e.data === 'pong') return; // 心跳响应
            this.onMessage(e.data);
        };
    }

    startHeartbeat() {
        this.heartbeatTimer = setInterval(() => {
            if (this.ws && this.ws.readyState === WebSocket.OPEN) {
                this.ws.send('ping');
            }
        }, this.heartbeatInterval);
    }

    stopHeartbeat() {
        if (this.heartbeatTimer) {
            clearInterval(this.heartbeatTimer);
            this.heartbeatTimer = null;
        }
    }

    attemptReconnect() {
        if (this.reconnectAttempts >= this.maxReconnectAttempts) return;
        this.reconnectAttempts++;
        const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts), 30000);
        setTimeout(() => this.connect(), delay);
    }

    onMessage(data) { /* 覆盖此方法 */ }

    send(data) {
        if (this.ws && this.ws.readyState === WebSocket.OPEN) {
            this.ws.send(data);
        }
    }

    close() {
        this.stopHeartbeat();
        this.reconnectAttempts = this.maxReconnectAttempts; // 阻止重连
        if (this.ws) this.ws.close(1000, 'Normal closure');
    }
}

2. 消息队列

代码示例

// 离线时缓存消息,上线后重发
class WebSocketWithQueue {
    constructor(url) {
        this.url = url;
        this.ws = null;
        this.messageQueue = [];
    }

    connect() {
        this.ws = new WebSocket(this.url);

        this.ws.onopen = () => {
            this.flushQueue();
        };
    }

    send(data) {
        if (this.ws && this.ws.readyState === WebSocket.OPEN) {
            this.ws.send(data);
        } else {
            this.messageQueue.push(data);
        }
    }

    flushQueue() {
        while (this.messageQueue.length > 0) {
            const data = this.messageQueue.shift();
            this.ws.send(data);
        }
    }
}

3. 安全考虑

  • 始终使用加密连接:使用 wss:// 而非 ws://

  • 验证服务器证书:确保连接的安全性

  • 消息内容校验:对消息内容进行校验和清理

  • 频率限制:实现消息频率限制,防止滥用


七、常见问题

常见问题

WebSocket 连接频繁断开?

原因:网络不稳定、代理服务器超时、服务器负载过高。
解决方案:实现心跳机制和指数退避重连策略。

如何处理 WebSocket 消息顺序?

解决方案:为消息添加序列号,接收端按序号排序处理。

WebSocket 和 SSE 如何选择?

解答:
• 需要双向通信 → WebSocket
• 仅需服务器推送 → SSE(更简单)
• 需要二进制数据 → WebSocket
• 需要自动重连 → SSE(内置)或 WebSocket(手动实现)

WebSocket 连接数有限制吗?

解答:浏览器对同一域名的 WebSocket 连接数有限制(通常 6-30 个),建议复用连接,通过消息类型区分不同业务。


八、总结

WebSocket 提供了浏览器与服务器之间的全双工通信能力,是构建实时 Web 应用的核心技术。使用时需实现心跳保活、断线重连、消息队列等机制确保连接的可靠性。安全方面应始终使用 wss:// 加密连接,并对消息内容进行校验。对于仅需服务器推送的场景,SSE 是更轻量的替代方案。合理选择通信方式,配合完善的状态管理,可以构建出稳定高效的实时应用。

标签: WebSocket 实时通信 全双工 心跳检测 断线重连

本文涉及AI创作

内容由AI创作,请仔细甄别

list快速访问

上一篇: HTML5 API:HTML5 Server-Sent Events - 完整教程与代码示例 下一篇: HTML5 API:HTML5 History API - 完整教程与代码示例

poll相关推荐