Files
registry/ui/src/app/core/services/reload.service.ts

87 lines
2.7 KiB
TypeScript
Raw Normal View History

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<string | null>(null);
private reconnectAttempts = 0;
private maxReconnectAttempts = 10;
private reconnectTimeout: ReturnType<typeof setTimeout> | 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');
}
}
}