JavaScript中的WebSocket与实时通信
字数 664 2025-11-10 09:16:47
JavaScript中的WebSocket与实时通信
描述
WebSocket是一种在单个TCP连接上进行全双工通信的协议,用于实现客户端和服务器之间的实时数据交换。与传统的HTTP请求-响应模式不同,WebSocket允许服务器主动向客户端推送数据,非常适合聊天应用、实时游戏、股票行情等需要低延迟通信的场景。
WebSocket基础概念
- 协议特点:WebSocket使用ws://或wss://(加密)协议,通过HTTP/1.1的Upgrade机制建立连接
- 握手过程:客户端发送包含Upgrade头部的HTTP请求,服务器响应101状态码完成协议切换
- 全双工通信:建立连接后,双方可以随时发送数据,无需等待请求
WebSocket API使用步骤
- 创建WebSocket实例:
const socket = new WebSocket('wss://echo.websocket.org'); // 使用公开测试服务
- 监听连接开启事件:
socket.onopen = function(event) {
console.log('连接已建立');
socket.send('Hello Server!'); // 连接成功后发送消息
};
- 处理接收消息事件:
socket.onmessage = function(event) {
console.log('收到消息:', event.data);
};
- 处理连接关闭事件:
socket.onclose = function(event) {
if (event.wasClean) {
console.log(`连接正常关闭 code=${event.code} reason=${event.reason}`);
} else {
console.log('连接异常断开');
}
};
- 处理错误事件:
socket.onerror = function(error) {
console.log('WebSocket错误:', error);
};
实际应用示例:简单聊天室
class ChatRoom {
constructor(url) {
this.socket = new WebSocket(url);
this.setupEventHandlers();
}
setupEventHandlers() {
this.socket.onopen = () => {
console.log('已进入聊天室');
};
this.socket.onmessage = (event) => {
const message = JSON.parse(event.data);
this.displayMessage(message);
};
this.socket.onclose = () => {
console.log('已退出聊天室');
};
}
sendMessage(text) {
const message = {
type: 'chat',
text: text,
timestamp: Date.now()
};
this.socket.send(JSON.stringify(message));
}
displayMessage(message) {
const div = document.createElement('div');
div.textContent = `[${new Date(message.timestamp).toLocaleTimeString()}] ${message.text}`;
document.getElementById('chat').appendChild(div);
}
}
心跳检测机制
由于网络不稳定可能导致连接意外断开,需要实现心跳检测:
class StableWebSocket extends WebSocket {
constructor(url, protocols) {
super(url, protocols);
this.heartbeatInterval = 30000; // 30秒
this.setupHeartbeat();
}
setupHeartbeat() {
this.pingInterval = setInterval(() => {
if (this.readyState === WebSocket.OPEN) {
this.send(JSON.stringify({type: 'ping'}));
}
}, this.heartbeatInterval);
this.addEventListener('message', (event) => {
const data = JSON.parse(event.data);
if (data.type === 'pong') {
console.log('心跳正常');
}
});
}
close() {
clearInterval(this.pingInterval);
super.close();
}
}
错误处理与重连机制
class ReconnectableWebSocket {
constructor(url) {
this.url = url;
this.reconnectAttempts = 0;
this.maxReconnectAttempts = 5;
this.connect();
}
connect() {
this.socket = new WebSocket(this.url);
this.socket.onopen = () => {
this.reconnectAttempts = 0;
console.log('WebSocket连接成功');
};
this.socket.onclose = (event) => {
if (event.code !== 1000) { // 非正常关闭
this.handleReconnect();
}
};
this.socket.onerror = (error) => {
console.error('WebSocket错误:', error);
};
}
handleReconnect() {
if (this.reconnectAttempts < this.maxReconnectAttempts) {
const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts), 30000);
console.log(`${delay}ms后尝试重连...`);
setTimeout(() => {
this.reconnectAttempts++;
this.connect();
}, delay);
} else {
console.error('达到最大重连次数,放弃连接');
}
}
}
性能优化建议
- 使用二进制数据:对于大量数据传输,使用ArrayBuffer代替JSON
- 消息压缩:对文本消息进行gzip压缩
- 连接复用:避免创建过多WebSocket连接
- 合理设置心跳间隔:平衡实时性和服务器负载
适用场景分析
- 适合:实时聊天、在线协作、实时数据监控、多人在线游戏
- 不适合:一次性数据获取、文件上传下载(优先考虑HTTP)
通过以上完整的WebSocket实现方案,可以构建稳定可靠的实时通信应用,满足不同场景下的实时数据交换需求。