Enhance Socket.IO integration and improve error handling
- Updated CORS configuration for Socket.IO to allow all origins and added specific allowed headers. - Improved error handling for Socket.IO connections, including detailed logging for connection errors and upgrade attempts. - Implemented cleanup logic for socket connections during page reloads to prevent stale connections. - Enhanced reconnection logic with unlimited attempts and improved logging for connection status. - Updated frontend socket service to manage club room joining and leaving more effectively, with better state handling. - Configured Vite for improved hot module replacement (HMR) settings to support local development.
This commit is contained in:
@@ -2,12 +2,61 @@ import { io } from 'socket.io-client';
|
||||
import { backendBaseUrl } from '../apiClient.js';
|
||||
|
||||
let socket = null;
|
||||
let isReloading = false;
|
||||
let suppressLogs = false;
|
||||
|
||||
// Cleanup beim Seitenreload
|
||||
if (typeof window !== 'undefined') {
|
||||
window.addEventListener('beforeunload', () => {
|
||||
isReloading = true;
|
||||
suppressLogs = true;
|
||||
if (socket) {
|
||||
// Trenne die Verbindung beim Reload, aber unterdrücke Logs
|
||||
socket.removeAllListeners();
|
||||
socket.disconnect();
|
||||
socket = null;
|
||||
}
|
||||
});
|
||||
|
||||
// Nach dem Reload Logs wieder erlauben (nach kurzer Verzögerung)
|
||||
window.addEventListener('load', () => {
|
||||
setTimeout(() => {
|
||||
isReloading = false;
|
||||
suppressLogs = false;
|
||||
}, 1000);
|
||||
});
|
||||
}
|
||||
|
||||
export const connectSocket = (clubId) => {
|
||||
// Beim ersten Connect nach Reload, entferne alte Socket.IO Cookies
|
||||
if (typeof document !== 'undefined' && !socket) {
|
||||
// Entferne alte Socket.IO Session-Cookies
|
||||
document.cookie.split(';').forEach((cookie) => {
|
||||
const eqPos = cookie.indexOf('=');
|
||||
const name = eqPos > -1 ? cookie.substr(0, eqPos).trim() : cookie.trim();
|
||||
if (name === 'io') {
|
||||
document.cookie = `${name}=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/`;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Wenn bereits eine Verbindung existiert, aber nicht verbunden ist, trenne sie
|
||||
if (socket && !socket.connected) {
|
||||
socket.removeAllListeners();
|
||||
socket.disconnect();
|
||||
socket = null;
|
||||
}
|
||||
|
||||
if (socket && socket.connected) {
|
||||
// Wenn bereits verbunden, verlasse den alten Club-Raum und trete dem neuen bei
|
||||
if (socket.currentClubId) {
|
||||
if (socket.currentClubId && socket.currentClubId !== clubId) {
|
||||
socket.emit('leave-club', socket.currentClubId);
|
||||
socket.currentClubId = clubId;
|
||||
socket.emit('join-club', clubId);
|
||||
return socket;
|
||||
} else if (socket.currentClubId === clubId) {
|
||||
// Bereits im richtigen Club-Raum - keine Aktion nötig
|
||||
return socket;
|
||||
}
|
||||
} else {
|
||||
// Neue Verbindung erstellen
|
||||
@@ -33,27 +82,98 @@ export const connectSocket = (clubId) => {
|
||||
transports: ['polling', 'websocket'], // Polling zuerst für bessere Kompatibilität, dann WebSocket
|
||||
reconnection: true,
|
||||
reconnectionDelay: 1000,
|
||||
reconnectionAttempts: 5,
|
||||
reconnectionDelayMax: 5000,
|
||||
reconnectionAttempts: Infinity, // Unbegrenzte Versuche
|
||||
timeout: 20000,
|
||||
upgrade: true,
|
||||
forceNew: false,
|
||||
secure: isHttps, // Nur für HTTPS
|
||||
rejectUnauthorized: false // Für selbst-signierte Zertifikate (nur Entwicklung)
|
||||
rejectUnauthorized: false, // Für selbst-signierte Zertifikate (nur Entwicklung)
|
||||
// Verbesserte Cookie-Handling
|
||||
withCredentials: true,
|
||||
// Auto-Connect
|
||||
autoConnect: true
|
||||
});
|
||||
|
||||
socket.on('connect', () => {
|
||||
console.log('✅ Socket.IO verbunden:', socket.id);
|
||||
console.log(' Transport:', socket.io.engine.transport.name);
|
||||
// Wenn bereits ein Club ausgewählt war, trete dem Raum bei
|
||||
if (socket.currentClubId) {
|
||||
socket.emit('join-club', socket.currentClubId);
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('disconnect', () => {
|
||||
// Socket getrennt
|
||||
socket.on('disconnect', (reason) => {
|
||||
// Beim Reload oder wenn Logs unterdrückt werden sollen, keine Logs
|
||||
if (isReloading || suppressLogs) {
|
||||
return;
|
||||
}
|
||||
|
||||
// "transport error" ist normal beim Reload - unterdrücke diese Logs komplett
|
||||
if (reason === 'transport error' || reason === 'ping timeout') {
|
||||
return; // Keine Logs für normale Transport-Fehler
|
||||
}
|
||||
|
||||
// Nur wichtige Disconnects loggen
|
||||
if (reason !== 'io client disconnect' && reason !== 'transport close') {
|
||||
console.log('❌ Socket.IO getrennt:', reason);
|
||||
}
|
||||
|
||||
if (reason === 'io server disconnect') {
|
||||
// Server hat die Verbindung getrennt, neu verbinden
|
||||
socket.connect();
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('connect_error', (error) => {
|
||||
console.error('Socket.IO Verbindungsfehler:', error);
|
||||
// Beim Reload keine Error-Logs
|
||||
if (isReloading || suppressLogs) {
|
||||
return;
|
||||
}
|
||||
|
||||
// "xhr poll error" oder "Session ID unknown" sind normal - unterdrücke diese
|
||||
if (error.message && (
|
||||
error.message.includes('Session ID unknown') ||
|
||||
error.message.includes('xhr poll error') ||
|
||||
error.type === 'TransportError'
|
||||
)) {
|
||||
// Keine Logs für normale Verbindungsfehler
|
||||
return;
|
||||
}
|
||||
|
||||
// Nur unerwartete Fehler loggen
|
||||
console.error('❌ Socket.IO Verbindungsfehler:', error.message);
|
||||
console.error(' Type:', error.type);
|
||||
console.error(' Description:', error.description);
|
||||
});
|
||||
|
||||
socket.on('reconnect', (attemptNumber) => {
|
||||
// Beim Reload keine Reconnect-Logs
|
||||
if (!isReloading && !suppressLogs) {
|
||||
console.log('✅ Socket.IO wieder verbunden nach', attemptNumber, 'Versuch(en)');
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('reconnect_attempt', (attemptNumber) => {
|
||||
// Reconnect-Versuche nicht loggen - zu viele Logs
|
||||
// if (!isReloading && !suppressLogs) {
|
||||
// console.log('🔄 Socket.IO Verbindungsversuch', attemptNumber);
|
||||
// }
|
||||
});
|
||||
|
||||
socket.on('reconnect_error', (error) => {
|
||||
// Beim Reload keine Error-Logs
|
||||
if (!isReloading && !suppressLogs) {
|
||||
console.error('❌ Socket.IO Wiederverbindungsfehler:', error.message);
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('reconnect_failed', () => {
|
||||
// Nur kritische Fehler loggen
|
||||
if (!isReloading && !suppressLogs) {
|
||||
console.error('❌ Socket.IO Wiederverbindung fehlgeschlagen - alle Versuche aufgebraucht');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -71,6 +191,7 @@ export const disconnectSocket = () => {
|
||||
if (socket.currentClubId) {
|
||||
socket.emit('leave-club', socket.currentClubId);
|
||||
}
|
||||
socket.removeAllListeners();
|
||||
socket.disconnect();
|
||||
socket = null;
|
||||
}
|
||||
|
||||
@@ -13,6 +13,11 @@ export default defineConfig({
|
||||
port: 5000,
|
||||
watch: {
|
||||
usePolling: true,
|
||||
},
|
||||
hmr: {
|
||||
protocol: 'ws',
|
||||
host: 'localhost',
|
||||
port: 5000,
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user