fix(websocket): use singleton socket to prevent disconnection on re-render
This commit is contained in:
parent
bd65a431aa
commit
0cd667b5c8
|
|
@ -2,6 +2,10 @@ import { useCallback, useEffect, useRef } from 'react';
|
||||||
import { io, Socket } from 'socket.io-client';
|
import { io, Socket } from 'socket.io-client';
|
||||||
import { useChatStore, Message } from '../stores/chatStore';
|
import { useChatStore, Message } from '../stores/chatStore';
|
||||||
|
|
||||||
|
// Singleton socket instance to prevent multiple connections
|
||||||
|
let globalSocket: Socket | null = null;
|
||||||
|
let currentUserId: string | null = null;
|
||||||
|
|
||||||
export function useChat() {
|
export function useChat() {
|
||||||
const socketRef = useRef<Socket | null>(null);
|
const socketRef = useRef<Socket | null>(null);
|
||||||
const {
|
const {
|
||||||
|
|
@ -16,14 +20,32 @@ export function useChat() {
|
||||||
setConnected,
|
setConnected,
|
||||||
} = useChatStore();
|
} = useChatStore();
|
||||||
|
|
||||||
// Initialize WebSocket connection
|
// Initialize WebSocket connection (singleton pattern)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!userId) return;
|
if (!userId) return;
|
||||||
|
|
||||||
|
// If socket exists for same user, reuse it
|
||||||
|
if (globalSocket && currentUserId === userId && globalSocket.connected) {
|
||||||
|
socketRef.current = globalSocket;
|
||||||
|
setConnected(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If socket exists for different user or disconnected, clean up
|
||||||
|
if (globalSocket) {
|
||||||
|
globalSocket.disconnect();
|
||||||
|
globalSocket = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentUserId = userId;
|
||||||
|
|
||||||
const socket = io('/ws/conversation', {
|
const socket = io('/ws/conversation', {
|
||||||
path: '/ws/conversation/socket.io',
|
path: '/ws/conversation/socket.io',
|
||||||
query: { userId },
|
query: { userId },
|
||||||
transports: ['websocket'],
|
transports: ['websocket'],
|
||||||
|
reconnection: true,
|
||||||
|
reconnectionAttempts: 5,
|
||||||
|
reconnectionDelay: 1000,
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('connect', () => {
|
socket.on('connect', () => {
|
||||||
|
|
@ -77,7 +99,6 @@ export function useChat() {
|
||||||
|
|
||||||
socket.on('tool_result', (data) => {
|
socket.on('tool_result', (data) => {
|
||||||
console.log('Tool result:', data);
|
console.log('Tool result:', data);
|
||||||
// Could update message with tool result
|
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('error', (error) => {
|
socket.on('error', (error) => {
|
||||||
|
|
@ -85,11 +106,10 @@ export function useChat() {
|
||||||
setStreaming(false);
|
setStreaming(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
globalSocket = socket;
|
||||||
socketRef.current = socket;
|
socketRef.current = socket;
|
||||||
|
|
||||||
return () => {
|
// Don't disconnect on cleanup - keep singleton alive
|
||||||
socket.disconnect();
|
|
||||||
};
|
|
||||||
}, [userId]);
|
}, [userId]);
|
||||||
|
|
||||||
// Send message
|
// Send message
|
||||||
|
|
@ -114,15 +134,16 @@ export function useChat() {
|
||||||
};
|
};
|
||||||
addMessage(conversationId, userMessage);
|
addMessage(conversationId, userMessage);
|
||||||
|
|
||||||
// Send via WebSocket
|
// Send via WebSocket (use globalSocket for reliability)
|
||||||
if (socketRef.current?.connected) {
|
const socket = globalSocket || socketRef.current;
|
||||||
|
if (socket?.connected) {
|
||||||
console.log('Sending message via WebSocket:', { conversationId, content: content.trim() });
|
console.log('Sending message via WebSocket:', { conversationId, content: content.trim() });
|
||||||
socketRef.current.emit('message', {
|
socket.emit('message', {
|
||||||
conversationId,
|
conversationId,
|
||||||
content: content.trim(),
|
content: content.trim(),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
console.error('WebSocket not connected, cannot send message');
|
console.error('WebSocket not connected, cannot send message. Socket state:', socket?.connected);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[userId, currentConversationId, addMessage],
|
[userId, currentConversationId, addMessage],
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue