Files
SimpleClient-releases/connection-manager.js
2025-09-11 19:55:15 -04:00

117 lines
3.5 KiB
JavaScript

/**
* 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;