/** * Gestionnaire de connexion avec fallback SignalR → WebSocket * Essaie d'abord SignalR, puis bascule sur WebSocket si nécessaire */ const signalR = require('@microsoft/signalr'); const WebSocketAdapter = require('./websocket-adapter'); class ConnectionManager { constructor(serverUrl, options = {}) { this.serverUrl = serverUrl; this.options = options; this.connection = null; this.isUsingWebSocketFallback = false; this.connectionType = 'none'; } /** * Établit la connexion en essayant SignalR puis WebSocket */ async connect() { console.log('🔌 Tentative de connexion au serveur...'); // 1. Essayer SignalR d'abord try { console.log('📡 Essai avec SignalR...'); this.connection = await this.createSignalRConnection(); await this.connection.start(); this.connectionType = 'SignalR'; this.isUsingWebSocketFallback = false; console.log('✅ Connexion SignalR établie'); return this.connection; } catch (signalRError) { console.warn('⚠️ SignalR indisponible:', signalRError.message); console.log('🔄 Basculement vers WebSocket...'); } // 2. Fallback vers WebSocket try { this.connection = new WebSocketAdapter(this.serverUrl, this.options); await this.connection.start(); this.connectionType = 'WebSocket'; this.isUsingWebSocketFallback = true; console.log('✅ Connexion WebSocket établie (mode fallback)'); return this.connection; } catch (wsError) { console.error('❌ Impossible de se connecter (SignalR et WebSocket ont échoué)'); throw wsError; } } /** * Crée une connexion SignalR */ createSignalRConnection() { const url = `http://${this.serverUrl}/signalR`; console.log(`Creating SignalR connection to: ${url}`); return new signalR.HubConnectionBuilder() .withUrl(url) .withAutomaticReconnect([0, 2000, 5000, 10000]) .configureLogging(signalR.LogLevel.Information) .build(); } /** * Retourne la connexion active */ getConnection() { return this.connection; } /** * Déconnecte proprement */ async disconnect() { if (this.connection) { await this.connection.stop(); this.connection = null; this.connectionType = 'none'; } } /** * Informations sur la connexion */ getConnectionInfo() { return { type: this.connectionType, isWebSocketFallback: this.isUsingWebSocketFallback, isConnected: this.connection && this.connection.state === 'Connected', serverUrl: this.serverUrl }; } /** * Méthode helper pour invoquer des méthodes sur la connexion */ async invoke(methodName, ...args) { if (!this.connection) { throw new Error('Pas de connexion active'); } return this.connection.invoke(methodName, ...args); } /** * Méthode helper pour écouter des événements */ on(eventName, handler) { if (!this.connection) { throw new Error('Pas de connexion active'); } this.connection.on(eventName, handler); } } module.exports = ConnectionManager;