diff --git a/src/services/core/network.service.ts b/src/services/core/network.service.ts index e4a29bc..3dae1ab 100644 --- a/src/services/core/network.service.ts +++ b/src/services/core/network.service.ts @@ -1,38 +1,33 @@ -import * as Comlink from 'comlink'; -import type { NetworkBackend } from '../../workers/network.worker'; -import Services from '../service'; // Attention à la dépendance circulaire, on va gérer ça +import * as Comlink from "comlink"; +import type { NetworkBackend } from "../../workers/network.worker"; +import Services from "../service"; export class NetworkService { private worker: Comlink.Remote; private workerInstance: Worker; - // Cache local pour répondre instantanément aux demandes synchrones de l'UI + // Cache local private localRelays: Record = {}; constructor(private bootstrapUrls: string[]) { this.workerInstance = new Worker( - new URL('../../workers/network.worker.ts', import.meta.url), - { type: 'module' } + new URL("../../workers/network.worker.ts", import.meta.url), + { type: "module" } ); this.worker = Comlink.wrap(this.workerInstance); } - // Initialisation appelée par Services.ts public async initRelays() { - // 1. Setup des callbacks : Quand le worker reçoit un message, il appelle ici await this.worker.setCallbacks( Comlink.proxy(this.onMessageReceived.bind(this)), Comlink.proxy(this.onStatusChange.bind(this)) ); - // 2. Lancer les connexions for (const url of this.bootstrapUrls) { this.addWebsocketConnection(url); } } - // --- MÉTHODES PUBLIQUES (API inchangée) --- - public async addWebsocketConnection(url: string) { await this.worker.connect(url); } @@ -44,14 +39,10 @@ export class NetworkService { } public async sendMessage(flag: string, content: string) { - // On transmet au worker - // Note: Le type 'any' est utilisé pour simplifier la compatibilité avec AnkFlag await this.worker.sendMessage(flag as any, content); } public updateRelay(url: string, spAddress: string) { - // Cette méthode était utilisée pour update l'état local. - // Maintenant c'est le worker qui gère la vérité, mais on garde le cache local. this.localRelays[url] = spAddress; } @@ -59,30 +50,46 @@ export class NetworkService { return this.localRelays; } + // 🔥 CORRECTION ICI : Ajout d'une boucle d'attente (Polling) public async getAvailableRelayAddress(): Promise { - // On demande au worker qui a la "vraie" info temps réel - const addr = await this.worker.getAvailableRelay(); - if (addr) return addr; + const maxRetries = 20; // 20 tentatives + const interval = 500; // toutes les 500ms = 10 secondes max - // Fallback ou attente... - throw new Error('Aucun relais disponible (NetworkWorker)'); + for (let i = 0; i < maxRetries; i++) { + // On demande au worker + const addr = await this.worker.getAvailableRelay(); + + if (addr && addr !== "") { + return addr; // Trouvé ! + } + + // Pas encore là ? On attend un peu... + if (i === 0) + console.log("[NetworkService] ⏳ Attente du Handshake relais..."); + await new Promise((r) => setTimeout(r, interval)); + } + + throw new Error( + "Timeout: Aucun relais disponible après 10s (Handshake non reçu ?)" + ); } - // --- INTERNES (CALLBACKS) --- + // --- INTERNES --- private async onMessageReceived(flag: string, content: string, url: string) { - // C'est ici qu'on fait le pont : NetworkWorker -> Main -> CoreWorker - // On passe par l'instance Singleton de Services pour atteindre le CoreWorker const services = await Services.getInstance(); await services.dispatchToWorker(flag, content, url); } - private onStatusChange(url: string, status: 'OPEN' | 'CLOSED', spAddress?: string) { - if (status === 'OPEN' && spAddress) { + private onStatusChange( + url: string, + status: "OPEN" | "CLOSED", + spAddress?: string + ) { + if (status === "OPEN" && spAddress) { this.localRelays[url] = spAddress; - } else if (status === 'CLOSED') { - this.localRelays[url] = ''; + } else if (status === "CLOSED") { + this.localRelays[url] = ""; } - // On pourrait notifier l'UI ici de l'état de la connexion } -} \ No newline at end of file +}