首页
/ MDN WebSocket API 指南:如何编写 WebSocket 客户端应用

MDN WebSocket API 指南:如何编写 WebSocket 客户端应用

2025-07-07 03:11:34作者:温玫谨Lighthearted

前言

WebSocket 技术为现代 Web 应用提供了全双工通信能力,使得客户端和服务器之间可以建立持久连接并实时交换数据。本文将深入讲解如何使用 WebSocket API 开发客户端应用程序,涵盖从建立连接到数据传输的完整流程。

WebSocket 基础概念

WebSocket 协议提供了在单个 TCP 连接上进行全双工通信的机制,与传统的 HTTP 轮询相比具有显著优势:

  • 更低的延迟
  • 更少的网络开销
  • 真正的实时通信能力

创建 WebSocket 连接

初始化 WebSocket 对象

要建立 WebSocket 连接,首先需要创建 WebSocket 对象:

const socket = new WebSocket(url, [protocols]);

参数说明:

  • url:连接地址,必须使用 wss://(安全)或 ws://(非安全)协议
  • protocols(可选):指定子协议,可以是字符串或字符串数组

示例:

// 使用单个协议
const chatSocket = new WebSocket("wss://example.com/chat", "chat-v1");

// 使用多个协议
const gameSocket = new WebSocket("wss://example.com/game", ["game-v1", "game-v2"]);

连接状态

WebSocket 对象有以下几种连接状态(通过 readyState 属性获取):

  • CONNECTING (0):连接尚未建立
  • OPEN (1):连接已建立,可以通信
  • CLOSING (2):连接正在关闭
  • CLOSED (3):连接已关闭或无法打开

错误处理

连接过程中可能出现各种错误,应该妥善处理:

socket.onerror = (error) => {
  console.error("WebSocket 错误:", error);
};

数据传输

发送数据

连接建立后,可以使用 send() 方法发送数据:

// 发送文本
socket.send("Hello Server!");

// 发送JSON数据
const message = {
  type: "chat",
  content: "你好!",
  timestamp: Date.now()
};
socket.send(JSON.stringify(message));

支持的数据类型包括:

  • 字符串(String)
  • Blob 对象
  • ArrayBuffer
  • TypedArray

接收数据

通过监听 message 事件处理服务器返回的数据:

socket.onmessage = (event) => {
  console.log("收到消息:", event.data);
  
  // 如果是JSON数据
  try {
    const data = JSON.parse(event.data);
    processMessage(data);
  } catch (e) {
    console.log("非JSON消息:", event.data);
  }
};

实际应用示例:聊天客户端

下面是一个完整的聊天客户端实现示例:

// 初始化WebSocket
const chatSocket = new WebSocket("wss://example.com/chat", "chat-protocol");

// 连接建立时
chatSocket.onopen = () => {
  console.log("连接已建立");
  sendLoginMessage();
};

// 接收消息时
chatSocket.onmessage = (event) => {
  const message = JSON.parse(event.data);
  
  switch(message.type) {
    case "login-response":
      handleLoginResponse(message);
      break;
    case "chat-message":
      displayChatMessage(message);
      break;
    case "user-list":
      updateUserList(message.users);
      break;
    default:
      console.warn("未知消息类型:", message.type);
  }
};

// 发送登录信息
function sendLoginMessage() {
  const message = {
    type: "login",
    username: "user123",
    token: "abc123xyz"
  };
  chatSocket.send(JSON.stringify(message));
}

// 发送聊天消息
function sendChatMessage(text) {
  const message = {
    type: "chat",
    content: text,
    timestamp: Date.now()
  };
  chatSocket.send(JSON.stringify(message));
}

连接管理

关闭连接

当不再需要连接时,应该正确关闭它:

// 正常关闭
socket.close();

// 带状态码和原因
socket.close(1000, "工作完成");

常用的关闭代码:

  • 1000:正常关闭
  • 1001:端点离开
  • 1002:协议错误
  • 1003:接收到不支持的数据类型

重连机制

在实际应用中,应该实现自动重连逻辑:

let reconnectAttempts = 0;
const maxReconnectAttempts = 5;

function connect() {
  const socket = new WebSocket("wss://example.com/chat");
  
  socket.onclose = () => {
    if(reconnectAttempts < maxReconnectAttempts) {
      reconnectAttempts++;
      setTimeout(connect, 1000 * Math.pow(2, reconnectAttempts));
    }
  };
  
  socket.onopen = () => {
    reconnectAttempts = 0;
  };
}

安全最佳实践

  1. 始终使用 WSS:生产环境必须使用加密的 WebSocket 连接(wss://)
  2. 验证来源:服务器应验证 Origin 头部
  3. 限制数据大小:防止拒绝服务攻击
  4. 输入验证:对所有接收的数据进行验证
  5. 速率限制:防止客户端发送过多消息

性能优化建议

  1. 二进制数据传输:对于大量数据,考虑使用 ArrayBuffer
  2. 消息批处理:将多个小消息合并发送
  3. 心跳机制:保持连接活跃
  4. 缓冲管理:监控 bufferedAmount 属性

常见问题解答

Q:WebSocket 和 HTTP 有什么区别? A:WebSocket 是持久化连接,支持全双工通信,而 HTTP 是无状态的请求-响应协议。

Q:如何检测连接是否正常? A:可以实现心跳机制,定期发送小消息并等待响应。

Q:WebSocket 有跨域限制吗? A:有,与 AJAX 请求遵循相同的同源策略,但服务器可以通过设置响应头来允许跨域连接。

总结

WebSocket API 为现代 Web 应用提供了强大的实时通信能力。通过本文的介绍,你应该已经掌握了如何创建 WebSocket 连接、发送和接收数据、处理连接生命周期以及实现安全可靠的通信。在实际项目中,结合具体需求选择合适的架构和优化策略,可以构建出高效稳定的实时应用程序。