跳转到内容

JavaScript WebSocket

来自代码酷

JavaScript WebSocket[编辑 | 编辑源代码]

WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议,允许客户端和服务器之间实时交换数据。与传统的 HTTP 请求不同,WebSocket 提供持久的连接,使得数据可以双向流动,适用于实时应用如聊天、在线游戏和股票行情推送。

介绍[编辑 | 编辑源代码]

WebSocket 协议(RFC 6455)通过一次 HTTP 握手升级为 WebSocket 连接,之后客户端和服务器可以随时发送数据,无需重新建立连接。相比轮询或长轮询(Long Polling),WebSocket 减少了延迟和带宽消耗。

关键特性[编辑 | 编辑源代码]

  • 全双工通信:客户端和服务器可以同时发送和接收数据。
  • 低延迟:无需重复建立连接。
  • 轻量级:数据帧头部较小,适合高频通信。
  • 跨域支持:可通过 CORS 或代理服务器实现。

基本用法[编辑 | 编辑源代码]

以下是一个简单的 WebSocket 客户端示例:

// 创建 WebSocket 连接(ws:// 表示非加密,wss:// 表示加密)
const socket = new WebSocket('ws://example.com/socket');

// 连接打开时触发
socket.addEventListener('open', (event) => {
    console.log('连接已建立');
    socket.send('Hello Server!'); // 发送消息
});

// 接收服务器消息
socket.addEventListener('message', (event) => {
    console.log('收到消息:', event.data);
});

// 连接关闭时触发
socket.addEventListener('close', (event) => {
    console.log('连接已关闭');
});

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

输出示例[编辑 | 编辑源代码]

假设服务器返回 "Welcome!",控制台输出如下:

连接已建立
收到消息: Welcome!

协议细节[编辑 | 编辑源代码]

WebSocket 握手阶段使用 HTTP 升级头:

GET /socket 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=

实际案例[编辑 | 编辑源代码]

实时聊天应用[编辑 | 编辑源代码]

以下是一个简单的聊天室实现:

const chatSocket = new WebSocket('wss://chat.example.com');

// 发送消息
document.getElementById('send-button').addEventListener('click', () => {
    const message = document.getElementById('message-input').value;
    chatSocket.send(JSON.stringify({ type: 'message', text: message }));
});

// 接收消息
chatSocket.addEventListener('message', (event) => {
    const data = JSON.parse(event.data);
    if (data.type === 'message') {
        const chatBox = document.getElementById('chat-box');
        chatBox.innerHTML += `<div>${data.text}</div>`;
    }
});

股票行情推送[编辑 | 编辑源代码]

使用 WebSocket 接收实时股价:

const stockSocket = new WebSocket('wss://stocks.example.com');

stockSocket.addEventListener('message', (event) => {
    const stocks = JSON.parse(event.data);
    stocks.forEach(stock => {
        console.log(`${stock.symbol}: $${stock.price}`);
    });
});

高级主题[编辑 | 编辑源代码]

二进制数据传输[编辑 | 编辑源代码]

WebSocket 支持发送二进制数据(如 ArrayBuffer 或 Blob):

socket.send(new Uint8Array([0x48, 0x65, 0x6c, 0x6c, 0x6f])); // 发送 "Hello" 的二进制形式

心跳机制[编辑 | 编辑源代码]

保持连接活跃的示例:

setInterval(() => {
    if (socket.readyState === WebSocket.OPEN) {
        socket.send('ping'); // 心跳包
    }
}, 30000); // 每30秒发送一次

状态管理[编辑 | 编辑源代码]

WebSocket 对象有以下状态(通过 socket.readyState 获取):

  • CONNECTING (0):连接中
  • OPEN (1):已连接
  • CLOSING (2):关闭中
  • CLOSED (3):已关闭

错误处理[编辑 | 编辑源代码]

常见错误及解决方案:

  • 连接失败:检查服务器是否支持 WebSocket 或网络是否通畅。
  • 协议不匹配:确保客户端和服务器的 WebSocket 版本一致。
  • 数据格式错误:验证发送的数据是否为字符串或二进制类型。

性能优化[编辑 | 编辑源代码]

  • 使用 wss://(加密)避免中间人攻击。
  • 压缩数据(如 JSON 或 Protocol Buffers)减少带宽。
  • 实现重连逻辑应对网络波动。

与其他技术对比[编辑 | 编辑源代码]

技术 特点 适用场景
频繁请求,高延迟 | 简单实时性要求低的应用
服务器保持连接直到有数据 | 中等实时性需求
服务器单向推送 | 实时通知(如新闻推送)
全双工,低延迟 | 高频双向通信(如游戏、聊天)

数学基础[编辑 | 编辑源代码]

WebSocket 的掩码计算(RFC 6455 要求客户端掩码数据): masked_data[i]=data[i]mask[imod4] 其中 表示异或操作。

可视化连接流程[编辑 | 编辑源代码]

ClientServerloop[数据交换]HTTP Upgrade Request101 Switching Protocols发送消息返回响应关闭连接ClientServer

总结[编辑 | 编辑源代码]

WebSocket 是现代 Web 应用中实现实时通信的核心技术,适用于需要低延迟和高频数据交换的场景。通过本文的示例和解释,开发者可以快速掌握其基本用法和高级特性。