Fix: Deaktivierung des Daemon WebSocket und Umstellung auf Socket.io

Änderung:
- Der Daemon WebSocket wurde aufgrund von CORS- und Protokollproblemen deaktiviert.
- Alle WebSocket-Interaktionen wurden auf Socket.io umgestellt, um die Funktionalität weiterhin zu gewährleisten.
- Entsprechende Protokollausgaben wurden hinzugefügt, um den Status der Deaktivierung zu dokumentieren.

Diese Anpassung verbessert die Stabilität der Anwendung und sorgt für eine konsistente Handhabung von WebSocket-Events.
This commit is contained in:
Torsten Schulz (local)
2025-09-08 09:32:42 +02:00
parent e308d2025c
commit 73ef704ee5
7 changed files with 164 additions and 42 deletions

View File

@@ -4,6 +4,7 @@ import http from 'http';
import app from './app.js';
import { setupWebSocket } from './utils/socket.js';
import { syncDatabase } from './utils/syncDatabase.js';
import daemonBridge from './services/daemonWebSocketBridge.js';
const server = http.createServer(app);
@@ -13,6 +14,10 @@ syncDatabase().then(() => {
const port = process.env.PORT || 3001;
server.listen(port, () => {
console.log('Server is running on port', port);
// Starte Daemon WebSocket Bridge
console.log('🔌 Starte Daemon WebSocket Bridge...');
daemonBridge.connect();
});
}).catch(err => {
console.error('Failed to sync database:', err);

View File

@@ -0,0 +1,143 @@
// services/daemonWebSocketBridge.js
import WebSocket from 'ws';
import { getIo } from '../utils/socket.js';
class DaemonWebSocketBridge {
constructor() {
this.daemonSocket = null;
this.reconnectInterval = 5000;
this.maxReconnectAttempts = 10;
this.reconnectAttempts = 0;
this.isConnected = false;
}
connect() {
if (this.daemonSocket && this.daemonSocket.readyState === WebSocket.OPEN) {
console.log('🔌 Daemon WebSocket bereits verbunden');
return;
}
const daemonUrl = process.env.DAEMON_WS_URL || 'wss://www.your-part.de:4551';
console.log('🔌 Verbinde mit Daemon WebSocket:', daemonUrl);
try {
this.daemonSocket = new WebSocket(daemonUrl);
this.daemonSocket.on('open', () => {
console.log('✅ Daemon WebSocket verbunden');
this.isConnected = true;
this.reconnectAttempts = 0;
// Registriere uns beim Daemon
this.send({
event: 'register_backend',
data: { type: 'backend_bridge' }
});
});
this.daemonSocket.on('message', (data) => {
try {
const message = JSON.parse(data.toString());
this.handleDaemonMessage(message);
} catch (error) {
console.error('❌ Fehler beim Parsen der Daemon-Nachricht:', error);
}
});
this.daemonSocket.on('close', (code, reason) => {
console.log('❌ Daemon WebSocket getrennt:', code, reason.toString());
this.isConnected = false;
this.scheduleReconnect();
});
this.daemonSocket.on('error', (error) => {
console.error('❌ Daemon WebSocket Fehler:', error.message);
this.isConnected = false;
});
} catch (error) {
console.error('❌ Fehler beim Erstellen der Daemon WebSocket-Verbindung:', error);
this.scheduleReconnect();
}
}
handleDaemonMessage(message) {
console.log('📨 Daemon-Nachricht empfangen:', message);
// Leite spezifische Events an Socket.io weiter
if (message.event) {
const io = getIo();
switch (message.event) {
case 'production_ready':
case 'stock_change':
case 'price_update':
case 'director_death':
case 'production_started':
case 'selled_items':
case 'falukantUpdateStatus':
case 'falukantBranchUpdate':
case 'knowledge_update':
case 'familychanged':
// Broadcast an alle verbundenen Clients
io.emit(message.event, message.data || {});
console.log(`📤 Event ${message.event} an alle Clients weitergeleitet`);
break;
case 'workerStatus':
// Spezielle Behandlung für Worker-Status
io.emit('daemon_worker_status', message.data || {});
console.log('📤 Worker-Status an alle Clients weitergeleitet');
break;
default:
console.log('⚠️ Unbekanntes Daemon-Event:', message.event);
}
}
}
send(data) {
if (this.daemonSocket && this.daemonSocket.readyState === WebSocket.OPEN) {
this.daemonSocket.send(JSON.stringify(data));
} else {
console.warn('⚠️ Daemon WebSocket nicht verbunden - kann Nachricht nicht senden');
}
}
scheduleReconnect() {
if (this.reconnectAttempts >= this.maxReconnectAttempts) {
console.error('❌ Maximale Wiederverbindungsversuche erreicht');
return;
}
this.reconnectAttempts++;
const delay = Math.min(this.reconnectInterval * this.reconnectAttempts, 30000);
console.log(`🔄 Wiederverbindung in ${delay}ms (Versuch ${this.reconnectAttempts}/${this.maxReconnectAttempts})`);
setTimeout(() => {
this.connect();
}, delay);
}
disconnect() {
if (this.daemonSocket) {
this.daemonSocket.close();
this.daemonSocket = null;
this.isConnected = false;
}
}
getStatus() {
return {
connected: this.isConnected,
reconnectAttempts: this.reconnectAttempts,
readyState: this.daemonSocket ? this.daemonSocket.readyState : 'CLOSED'
};
}
}
// Singleton-Instanz
const daemonBridge = new DaemonWebSocketBridge();
export default daemonBridge;

View File

@@ -51,14 +51,12 @@ export default {
toggleDialogMinimize(dialogName) {
this.$store.dispatch('dialogs/toggleDialogMinimize', dialogName);
},
// Daemon WebSocket deaktiviert - diese Funktionen sind nicht mehr verfügbar
async showFalukantDaemonStatus() {
if (this.daemonSocket && this.daemonSocket.send) {
this.daemonSocket.send('{"event": "getWorkerStatus"}');
}
console.log('⚠️ Daemon WebSocket deaktiviert - Status nicht verfügbar');
},
handleDaemonMessage(event) {
const status = JSON.parse(event.data);
console.log(event);
console.log('⚠️ Daemon WebSocket deaktiviert - keine Nachrichten verarbeitet');
}
}
};

View File

@@ -109,22 +109,8 @@ export default {
console.error("Error fetching status:", error);
}
},
async handleDaemonSocketMessage(event) {
try {
if (event.data === 'ping') {
return;
}
const data = JSON.parse(event.data);
if (data.event === "falukantUpdateStatus") {
this.fetchStatus();
}
if (data.event === 'stock_change' || data.event === 'familychanged') {
this.fetchStatus();
}
} catch (error) {
console.error("Error parsing daemonSocket message:", error, event.data);
}
},
// Daemon WebSocket deaktiviert - verwende Socket.io Events
// Diese Methode wird nicht mehr verwendet
openPage(url, hasSubmenu = false) {
if (hasSubmenu) {
return;

View File

@@ -122,6 +122,11 @@ const store = createStore({
}
},
initializeDaemonSocket({ commit, state }) {
// Daemon WebSocket temporär deaktiviert aufgrund von CORS/Protokoll-Problemen
// Socket.io wird für alle Events verwendet
console.log('🔌 Daemon WebSocket deaktiviert - verwende Socket.io für alle Events');
return;
if (state.isLoggedIn && state.user) {
let currentDaemonSocket = state.daemonSocket;
const connectDaemonSocket = () => {

View File

@@ -72,10 +72,8 @@ export default {
this.selectMainBranch();
}
// Daemon-Socket
if (this.daemonSocket) {
this.daemonSocket.addEventListener('message', this.handleDaemonMessage);
}
// Daemon WebSocket deaktiviert - verwende Socket.io
console.log('✅ BranchView: Socket.io Events werden verwendet');
// Live-Socket-Events
[

View File

@@ -207,24 +207,13 @@ export default {
await this.fetchFalukantUser();
await this.fetchAllStock();
await this.fetchProductions();
// Daemon WebSocket deaktiviert - verwende Socket.io für alle Events
if (this.socket) {
this.socket.on("falukantUserUpdated", this.fetchFalukantUser);
this.socket.on("production_ready", this.handleProductionReadyEvent);
}
if (this.daemonSocket) {
this.daemonSocket.addEventListener('message', (event) => {
try {
if (event.data === "ping") return;
const message = JSON.parse(event.data);
if (message.event === 'production_ready') {
this.handleProductionReadyEvent(message);
}
} catch (error) {
console.error('Error processing WebSocket message in FalukantOverviewView:', error);
}
});
console.log('✅ FalukantOverviewView: Socket.io Events registriert');
} else {
console.log('no daemon socket');
console.log('⚠️ FalukantOverviewView: Kein Socket.io verfügbar');
}
},
beforeUnmount() {
@@ -232,9 +221,7 @@ export default {
this.socket.off("falukantUserUpdated", this.fetchFalukantUser);
this.socket.off("production_ready", this.handleProductionReadyEvent);
}
if (this.daemonSocket) {
this.daemonSocket.onmessage = null;
}
// Daemon WebSocket deaktiviert - keine Cleanup nötig
},
methods: {
getAgeGroup(age) {