diff --git a/src/providers/SocketProvider.tsx b/src/providers/SocketProvider.tsx index d8844cc62..8cafebf99 100644 --- a/src/providers/SocketProvider.tsx +++ b/src/providers/SocketProvider.tsx @@ -16,12 +16,14 @@ const SocketProvider = ({ children }: { children: React.ReactNode }) => { // Token was set - connect if (token && token !== previousToken) { + console.log('[SocketProvider] Token available, connecting...'); socketService.connect(token); previousTokenRef.current = token; } // Token was unset - disconnect if (!token && previousToken) { + console.log('[SocketProvider] Token removed, disconnecting...'); socketService.disconnect(); previousTokenRef.current = null; } diff --git a/src/services/socketService.ts b/src/services/socketService.ts index 730263284..381f154e7 100644 --- a/src/services/socketService.ts +++ b/src/services/socketService.ts @@ -11,19 +11,30 @@ class SocketService { * Connect to the socket server with authentication */ connect(token: string): void { + if (!token) { + console.warn('[Socket] Cannot connect: no token provided'); + return; + } + // Don't connect if already connected with the same token if (this.socket?.connected && this.token === token) { + console.log('[Socket] Already connected with same token'); return; } - // Disconnect existing connection if token changed - if (this.socket && this.token !== token) { - this.disconnect(); - } - - // Don't connect if socket exists and is not disconnected (already connecting or connected) - if (this.socket && !this.socket.disconnected) { - return; + // Disconnect existing connection if token changed or socket exists + if (this.socket) { + if (this.token !== token) { + console.log('[Socket] Token changed, disconnecting old connection'); + this.disconnect(); + } else if (this.socket.connected) { + console.log('[Socket] Already connected'); + return; + } else if (!this.socket.disconnected) { + // Socket is connecting, wait for it + console.log('[Socket] Connection in progress, waiting...'); + return; + } } this.token = token; @@ -31,31 +42,54 @@ class SocketService { // Update status to connecting store.dispatch(setStatus('connecting')); + console.log('[Socket] Connecting to:', BACKEND_URL); + console.log('[Socket] Token present:', token ? 'yes' : 'no'); + console.log('[Socket] Token length:', token?.length || 0); + // Create socket connection with auth token + // Note: path must match backend server configuration + // Backend expects token in socket.handshake.auth.token this.socket = io(BACKEND_URL, { auth: { - token, + token: token, // Explicitly pass token in auth object }, + path: '/socket.io/', transports: ['websocket', 'polling'], reconnection: true, reconnectionDelay: 1000, reconnectionAttempts: 5, + forceNew: true, // Force new connection to ensure auth is sent }); // Connection event handlers this.socket.on('connect', () => { const socketId = this.socket?.id || null; + console.log('[Socket] Connected with ID:', socketId); store.dispatch(setStatus('connected')); store.dispatch(setSocketId(socketId)); }); - this.socket.on('disconnect', () => { + this.socket.on('ready', () => { + console.log('[Socket] Server ready - authentication successful'); + }); + + this.socket.on('error', (error: { message?: string; status?: number }) => { + console.error('[Socket] Server error:', error); + if (error.status === 403) { + console.error('[Socket] Authentication failed - plan limit or access denied'); + } + }); + + this.socket.on('disconnect', (reason) => { + console.log('[Socket] Disconnected:', reason); store.dispatch(setStatus('disconnected')); store.dispatch(setSocketId(null)); }); this.socket.on('connect_error', (error) => { console.error('[Socket] Connection error:', error); + console.error('[Socket] Error message:', error.message); + console.error('[Socket] Error type:', error.type); store.dispatch(setStatus('disconnected')); }); } diff --git a/src/store/index.ts b/src/store/index.ts index 1964fc2d8..5d10339c4 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -13,7 +13,7 @@ import storage from "redux-persist/lib/storage"; import authReducer from "./authSlice"; import socketReducer from "./socketSlice"; import userReducer from "./userSlice"; -import createLogger from "redux-logger"; +import { createLogger } from "redux-logger"; import { IS_DEV } from "../utils/config"; // Persist config for auth only @@ -39,8 +39,16 @@ export const store = configureStore({ }, }); - // Add redux-logger in development - if (IS_DEV) return middleware.concat(createLogger); + // Add redux-logger in development with collapsed groups + if (IS_DEV) { + return middleware.concat( + createLogger({ + collapsed: true, + duration: true, + timestamp: true, + }), + ); + } return middleware; }, });