chore: bump version to 0.7.1
This commit is contained in:
236
frontend/src/utils/websocketService.js
Normal file
236
frontend/src/utils/websocketService.js
Normal file
@@ -0,0 +1,236 @@
|
||||
/**
|
||||
* WebSocket通信服务模块
|
||||
* 负责与后端WebSocket通信、连接管理和消息处理
|
||||
*/
|
||||
import { ref } from 'vue';
|
||||
|
||||
class WebSocketService {
|
||||
constructor() {
|
||||
this.socket = null;
|
||||
this.wsUrl = ref('ws://127.0.0.1:5000/ws');
|
||||
this.reconnectInterval = 1000; // 重连间隔(毫秒)
|
||||
this.reconnectTimer = null;
|
||||
this.pingInterval = null;
|
||||
this.messageHandlers = new Map(); // 消息处理器映射
|
||||
this.isConnecting = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置WebSocket服务器URL
|
||||
* @param {string} url - WebSocket服务器URL(ws://或wss://协议)
|
||||
*/
|
||||
setWsUrl(url) {
|
||||
this.wsUrl.value = url;
|
||||
console.log('WebSocket URL已设置为:', url);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册消息处理器
|
||||
* @param {string} messageType - 消息类型
|
||||
* @param {Function} handler - 处理函数,接收消息数据参数
|
||||
*/
|
||||
registerHandler(messageType, handler) {
|
||||
this.messageHandlers.set(messageType, handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除消息处理器
|
||||
* @param {string} messageType - 要移除处理器的消息类型
|
||||
*/
|
||||
removeHandler(messageType) {
|
||||
this.messageHandlers.delete(messageType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除所有消息处理器
|
||||
*/
|
||||
clearHandlers() {
|
||||
this.messageHandlers.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* 连接到WebSocket服务器
|
||||
*/
|
||||
connect() {
|
||||
if (this.isConnecting || (this.socket && this.socket.readyState === WebSocket.OPEN)) {
|
||||
console.log('WebSocket已连接或正在连接中,不需要重新连接');
|
||||
return;
|
||||
}
|
||||
|
||||
this.isConnecting = true;
|
||||
|
||||
try {
|
||||
console.log('尝试连接WebSocket:', this.wsUrl.value);
|
||||
this.socket = new WebSocket(this.wsUrl.value);
|
||||
|
||||
this.socket.onopen = () => {
|
||||
console.log('WebSocket连接成功');
|
||||
this.isConnecting = false;
|
||||
|
||||
// 发送初始化请求,请求当前状态
|
||||
this.sendMessage({ type: 'request_status' });
|
||||
|
||||
if (this.reconnectTimer) {
|
||||
clearTimeout(this.reconnectTimer);
|
||||
this.reconnectTimer = null;
|
||||
}
|
||||
|
||||
// 启动定期ping,保持连接活跃
|
||||
this.startPingInterval();
|
||||
};
|
||||
|
||||
this.socket.onmessage = (event) => {
|
||||
this.handleMessage(event);
|
||||
};
|
||||
|
||||
this.socket.onclose = (event) => {
|
||||
console.log(`WebSocket连接关闭,代码: ${event.code},原因: ${event.reason}`);
|
||||
|
||||
this.isConnecting = false;
|
||||
this.socket = null;
|
||||
|
||||
// 清理ping定时器
|
||||
if (this.pingInterval) {
|
||||
clearInterval(this.pingInterval);
|
||||
this.pingInterval = null;
|
||||
}
|
||||
|
||||
// 尝试重连
|
||||
this.scheduleReconnect();
|
||||
};
|
||||
|
||||
this.socket.onerror = (error) => {
|
||||
console.error('WebSocket错误:', error);
|
||||
this.isConnecting = false;
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('创建WebSocket连接错误:', error);
|
||||
this.isConnecting = false;
|
||||
|
||||
// 连接失败时也应设置重连
|
||||
this.scheduleReconnect();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 安排重新连接
|
||||
*/
|
||||
scheduleReconnect() {
|
||||
if (!this.reconnectTimer) {
|
||||
this.reconnectTimer = setTimeout(() => {
|
||||
console.log('尝试重新连接WebSocket...');
|
||||
this.reconnectTimer = null;
|
||||
this.connect();
|
||||
}, this.reconnectInterval);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动定期发送ping消息的定时器
|
||||
*/
|
||||
startPingInterval() {
|
||||
// 清理现有的ping定时器
|
||||
if (this.pingInterval) {
|
||||
clearInterval(this.pingInterval);
|
||||
}
|
||||
|
||||
// 每10秒发送一次ping消息保持连接
|
||||
this.pingInterval = setInterval(() => {
|
||||
this.sendPing();
|
||||
}, 10000);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送ping消息
|
||||
*/
|
||||
sendPing() {
|
||||
if (this.socket?.readyState === WebSocket.OPEN) {
|
||||
console.log('发送ping消息保持连接');
|
||||
this.sendMessage({ type: 'ping' });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送消息到WebSocket服务器
|
||||
* @param {Object} data - 要发送的消息对象
|
||||
* @returns {boolean} - 是否成功发送
|
||||
*/
|
||||
sendMessage(data) {
|
||||
if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {
|
||||
console.warn('WebSocket未连接,无法发送消息');
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
this.socket.send(JSON.stringify(data));
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('发送WebSocket消息失败:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理接收到的WebSocket消息
|
||||
* @param {MessageEvent} event - WebSocket消息事件
|
||||
*/
|
||||
handleMessage(event) {
|
||||
try {
|
||||
const data = JSON.parse(event.data);
|
||||
console.log('收到WebSocket消息类型:', data.type);
|
||||
|
||||
// 调用对应类型的消息处理器
|
||||
if (data.type && this.messageHandlers.has(data.type)) {
|
||||
this.messageHandlers.get(data.type)(data);
|
||||
} else {
|
||||
console.log('没有对应的处理器,消息类型:', data.type);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('处理WebSocket消息错误:', error, '原始数据:', event.data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查并恢复WebSocket连接
|
||||
*/
|
||||
checkAndRestoreConnection() {
|
||||
console.log('检查WebSocket连接状态');
|
||||
|
||||
if (!this.socket || this.socket.readyState === WebSocket.CLOSED || this.socket.readyState === WebSocket.CLOSING) {
|
||||
console.log('WebSocket未连接或已关闭,尝试重新连接');
|
||||
this.connect();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭WebSocket连接
|
||||
*/
|
||||
disconnect() {
|
||||
// 清理ping定时器
|
||||
if (this.pingInterval) {
|
||||
clearInterval(this.pingInterval);
|
||||
this.pingInterval = null;
|
||||
}
|
||||
|
||||
// 清理重连定时器
|
||||
if (this.reconnectTimer) {
|
||||
clearTimeout(this.reconnectTimer);
|
||||
this.reconnectTimer = null;
|
||||
}
|
||||
|
||||
// 关闭WebSocket连接
|
||||
if (this.socket) {
|
||||
try {
|
||||
this.socket.close();
|
||||
} catch (error) {
|
||||
console.error('关闭WebSocket连接错误:', error);
|
||||
}
|
||||
this.socket = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 创建单例实例
|
||||
const websocketService = new WebSocketService();
|
||||
|
||||
export default websocketService;
|
||||
Reference in New Issue
Block a user