@@ -101,7 +101,21 @@ export function SocketProvider({ children, user }: SocketProviderProps) {
101101
102102 // Initialize socket when user is available
103103 useEffect ( ( ) => {
104- if ( ! user ?. id || socket ) return
104+ if ( ! user ?. id ) return
105+
106+ // Prevent duplicate connections - disconnect existing socket first
107+ if ( socket ) {
108+ logger . info ( 'Disconnecting existing socket before creating new one' )
109+ socket . disconnect ( )
110+ setSocket ( null )
111+ setIsConnected ( false )
112+ }
113+
114+ // Prevent multiple simultaneous initialization attempts
115+ if ( isConnecting ) {
116+ logger . info ( 'Socket initialization already in progress, skipping' )
117+ return
118+ }
105119
106120 logger . info ( 'Initializing socket connection for user:' , user . id )
107121 setIsConnecting ( true )
@@ -282,8 +296,16 @@ export function SocketProvider({ children, user }: SocketProviderProps) {
282296 // Start the socket initialization
283297 initializeSocket ( )
284298
285- // Cleanup on unmount
299+ // Cleanup on unmount or user change
286300 return ( ) => {
301+ if ( socket ) {
302+ logger . info ( 'Cleaning up socket connection' )
303+ socket . disconnect ( )
304+ setSocket ( null )
305+ setIsConnected ( false )
306+ setIsConnecting ( false )
307+ }
308+
287309 positionUpdateTimeouts . current . forEach ( ( timeoutId ) => {
288310 clearTimeout ( timeoutId )
289311 } )
@@ -295,15 +317,30 @@ export function SocketProvider({ children, user }: SocketProviderProps) {
295317 // Join workflow room
296318 const joinWorkflow = useCallback (
297319 ( workflowId : string ) => {
298- if ( socket && user ?. id ) {
299- logger . info ( `Joining workflow: ${ workflowId } ` )
300- socket . emit ( 'join-workflow' , {
301- workflowId, // Server gets user info from authenticated session
302- } )
303- setCurrentWorkflowId ( workflowId )
320+ if ( ! socket || ! user ?. id ) {
321+ logger . warn ( 'Cannot join workflow: socket or user not available' )
322+ return
304323 }
324+
325+ // Prevent duplicate joins to the same workflow
326+ if ( currentWorkflowId === workflowId ) {
327+ logger . info ( `Already in workflow ${ workflowId } , skipping join` )
328+ return
329+ }
330+
331+ // Leave current workflow first if we're in one
332+ if ( currentWorkflowId ) {
333+ logger . info ( `Leaving current workflow ${ currentWorkflowId } before joining ${ workflowId } ` )
334+ socket . emit ( 'leave-workflow' )
335+ }
336+
337+ logger . info ( `Joining workflow: ${ workflowId } ` )
338+ socket . emit ( 'join-workflow' , {
339+ workflowId, // Server gets user info from authenticated session
340+ } )
341+ setCurrentWorkflowId ( workflowId )
305342 } ,
306- [ socket , user ]
343+ [ socket , user , currentWorkflowId ]
307344 )
308345
309346 // Leave current workflow room
0 commit comments