dajiangroute/tiles/websocket.js
2025-09-13 17:38:35 +08:00

117 lines
3.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

class WebSocketClient {
constructor(url) {
this.url = url;
this.socket = null;
this.connected = false;
this.reconnecting = false;
this.reconnectInterval = 3000; // 重连间隔(ms)
this.maxReconnectAttempts = 10; // 最大重连次数
this.reconnectAttempts = 0;
this.messageQueue = []; // 消息队列
// 事件回调
this.onConnect = null;
this.onMessage = null;
this.onClose = null;
this.onError = null;
}
// 连接WebSocket服务器
connect() {
if (this.socket && (this.socket.readyState === WebSocket.CONNECTING || this.socket.readyState === WebSocket.OPEN)) {
return;
}
this.socket = new WebSocket(this.url);
this.socket.onopen = (event) => {
this.connected = true;
this.reconnecting = false;
this.reconnectAttempts = 0;
console.log('WebSocket连接已建立');
// 发送队列中的所有消息
this._sendQueuedMessages();
if (typeof this.onConnect === 'function') {
this.onConnect(event);
}
};
this.socket.onmessage = (event) => {
console.log('收到消息:', event.data);
this.onMessage(event.data);
};
this.socket.onclose = (event) => {
this.connected = false;
console.log('WebSocket连接已关闭代码:', event.code, '原因:', event.reason);
if (typeof this.onClose === 'function') {
this.onClose(event);
}
// 非主动关闭时尝试重连
if (!this.reconnecting && event.code !== 1000) {
this._scheduleReconnect();
}
};
this.socket.onerror = (error) => {
console.error('WebSocket错误:', error);
if (typeof this.onError === 'function') {
this.onError(error);
}
};
}
// 发送消息
send(message) {
if (this.connected && this.socket.readyState === WebSocket.OPEN) {
this.socket.send(message);
} else {
// 连接未建立,将消息加入队列
this.messageQueue.push(message);
if (!this.reconnecting) {
this._scheduleReconnect();
}
}
}
// 关闭连接
close(code = 1000, reason = '') {
this.reconnecting = false;
if (this.socket) {
this.socket.close(code, reason);
}
}
// 安排重连
_scheduleReconnect() {
if (this.reconnectAttempts < this.maxReconnectAttempts) {
this.reconnecting = true;
this.reconnectAttempts++;
const delay = this.reconnectInterval * Math.min(1, this.reconnectAttempts / 3); // 指数退避
console.log(`尝试重连 (${this.reconnectAttempts}/${this.maxReconnectAttempts})${delay/1000}秒后...`);
setTimeout(() => {
console.log('正在重连...');
this.connect();
}, delay);
} else {
console.error('达到最大重连次数,停止重连');
this.reconnecting = false;
}
}
// 发送队列中的消息
_sendQueuedMessages() {
if (this.messageQueue.length > 0) {
console.log(`发送队列中的${this.messageQueue.length}条消息`);
this.messageQueue.forEach(message => {
this.socket.send(message);
});
this.messageQueue = [];
}
}
}