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;
};
}
安全最佳实践
- 始终使用 WSS:生产环境必须使用加密的 WebSocket 连接(wss://)
- 验证来源:服务器应验证 Origin 头部
- 限制数据大小:防止拒绝服务攻击
- 输入验证:对所有接收的数据进行验证
- 速率限制:防止客户端发送过多消息
性能优化建议
- 二进制数据传输:对于大量数据,考虑使用 ArrayBuffer
- 消息批处理:将多个小消息合并发送
- 心跳机制:保持连接活跃
- 缓冲管理:监控 bufferedAmount 属性
常见问题解答
Q:WebSocket 和 HTTP 有什么区别? A:WebSocket 是持久化连接,支持全双工通信,而 HTTP 是无状态的请求-响应协议。
Q:如何检测连接是否正常? A:可以实现心跳机制,定期发送小消息并等待响应。
Q:WebSocket 有跨域限制吗? A:有,与 AJAX 请求遵循相同的同源策略,但服务器可以通过设置响应头来允许跨域连接。
总结
WebSocket API 为现代 Web 应用提供了强大的实时通信能力。通过本文的介绍,你应该已经掌握了如何创建 WebSocket 连接、发送和接收数据、处理连接生命周期以及实现安全可靠的通信。在实际项目中,结合具体需求选择合适的架构和优化策略,可以构建出高效稳定的实时应用程序。