dajiangroute/tiles/websocket.js

117 lines
3.5 KiB
JavaScript
Raw Normal View History

2025-09-13 17:38:35 +08:00
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 = [];
}
}
}