import { Injectable, signal } from '@angular/core'; /** * Service for automatic page reload when server restarts. * Connects to WebSocket endpoint and monitors server instance ID. * When server restarts with new ID, page automatically reloads. */ @Injectable({ providedIn: 'root' }) export class ReloadService { private ws: WebSocket | null = null; private instanceId = signal(null); private reconnectAttempts = 0; private maxReconnectAttempts = 10; private reconnectTimeout: ReturnType | null = null; constructor() { this.connect(); } private connect(): void { // Clean up any existing connection if (this.ws) { this.ws.close(); this.ws = null; } const protocol = location.protocol === 'https:' ? 'wss:' : 'ws:'; const wsUrl = `${protocol}//${location.host}/ws/reload`; try { this.ws = new WebSocket(wsUrl); this.ws.onopen = () => { console.log('[ReloadService] Connected to server'); this.reconnectAttempts = 0; }; this.ws.onmessage = (event) => { try { const data = JSON.parse(event.data); if (data.type === 'instance') { const currentId = this.instanceId(); if (currentId !== null && currentId !== data.id) { // Server restarted with new ID - reload page console.log('[ReloadService] Server restarted, reloading...'); location.reload(); } else { console.log(`[ReloadService] Instance ID: ${data.id}`); } this.instanceId.set(data.id); } } catch (e) { console.error('[ReloadService] Failed to parse message:', e); } }; this.ws.onclose = () => { console.log('[ReloadService] Connection closed'); this.scheduleReconnect(); }; this.ws.onerror = (error) => { console.error('[ReloadService] WebSocket error:', error); this.ws?.close(); }; } catch (e) { console.error('[ReloadService] Failed to create WebSocket:', e); this.scheduleReconnect(); } } private scheduleReconnect(): void { if (this.reconnectTimeout) { clearTimeout(this.reconnectTimeout); } if (this.reconnectAttempts < this.maxReconnectAttempts) { const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts), 10000); this.reconnectAttempts++; console.log(`[ReloadService] Reconnecting in ${delay}ms (attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts})`); this.reconnectTimeout = setTimeout(() => this.connect(), delay); } else { console.log('[ReloadService] Max reconnect attempts reached'); } } }