Dateien
AegisSight-Monitor/src/static/js/ws.js

106 Zeilen
2.7 KiB
JavaScript

/**
* WebSocket-Client für Echtzeit-Updates.
*/
const WS = {
socket: null,
reconnectDelay: 2000,
maxReconnectDelay: 30000,
_handlers: {},
_pingInterval: null,
connect() {
const token = localStorage.getItem('osint_token');
if (!token) return;
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
const url = `${protocol}//${window.location.host}/api/ws`;
try {
this.socket = new WebSocket(url);
} catch (e) {
console.error('WebSocket-Verbindungsfehler:', e);
this._scheduleReconnect();
return;
}
this.socket.onopen = () => {
// Token als erste Nachricht senden (nicht in URL)
this.socket.send(token);
};
this.socket.onmessage = (event) => {
if (event.data === 'pong') return;
if (event.data === 'authenticated') {
console.log('WebSocket verbunden');
this.reconnectDelay = 2000;
this._startPing();
return;
}
try {
const msg = JSON.parse(event.data);
this._dispatch(msg);
} catch (e) {
console.error('WebSocket Parse-Fehler:', e);
}
};
this.socket.onclose = () => {
console.log('WebSocket getrennt');
this._stopPing();
this._scheduleReconnect();
};
this.socket.onerror = () => {};
},
disconnect() {
this._stopPing();
if (this.socket) {
this.socket.close();
this.socket = null;
}
},
on(type, handler) {
if (!this._handlers[type]) {
this._handlers[type] = [];
}
this._handlers[type].push(handler);
},
_dispatch(msg) {
const handlers = this._handlers[msg.type] || [];
handlers.forEach(h => h(msg));
// Globale Handler
const allHandlers = this._handlers['*'] || [];
allHandlers.forEach(h => h(msg));
},
_startPing() {
this._pingInterval = setInterval(() => {
if (this.socket && this.socket.readyState === WebSocket.OPEN) {
this.socket.send('ping');
}
}, 30000);
},
_stopPing() {
if (this._pingInterval) {
clearInterval(this._pingInterval);
this._pingInterval = null;
}
},
_scheduleReconnect() {
setTimeout(() => {
if (!this.socket || this.socket.readyState === WebSocket.CLOSED) {
this.connect();
}
}, this.reconnectDelay);
this.reconnectDelay = Math.min(this.reconnectDelay * 1.5, this.maxReconnectDelay);
},
};