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 { 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() {
|
||||
const socketRef = useRef<Socket | null>(null);
|
||||
const {
|
||||
|
|
@ -16,14 +20,32 @@ export function useChat() {
|
|||
setConnected,
|
||||
} = useChatStore();
|
||||
|
||||
// Initialize WebSocket connection
|
||||
// Initialize WebSocket connection (singleton pattern)
|
||||
useEffect(() => {
|
||||
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', {
|
||||
path: '/ws/conversation/socket.io',
|
||||
query: { userId },
|
||||
transports: ['websocket'],
|
||||
reconnection: true,
|
||||
reconnectionAttempts: 5,
|
||||
reconnectionDelay: 1000,
|
||||
});
|
||||
|
||||
socket.on('connect', () => {
|
||||
|
|
@ -77,7 +99,6 @@ export function useChat() {
|
|||
|
||||
socket.on('tool_result', (data) => {
|
||||
console.log('Tool result:', data);
|
||||
// Could update message with tool result
|
||||
});
|
||||
|
||||
socket.on('error', (error) => {
|
||||
|
|
@ -85,11 +106,10 @@ export function useChat() {
|
|||
setStreaming(false);
|
||||
});
|
||||
|
||||
globalSocket = socket;
|
||||
socketRef.current = socket;
|
||||
|
||||
return () => {
|
||||
socket.disconnect();
|
||||
};
|
||||
// Don't disconnect on cleanup - keep singleton alive
|
||||
}, [userId]);
|
||||
|
||||
// Send message
|
||||
|
|
@ -114,15 +134,16 @@ export function useChat() {
|
|||
};
|
||||
addMessage(conversationId, userMessage);
|
||||
|
||||
// Send via WebSocket
|
||||
if (socketRef.current?.connected) {
|
||||
// Send via WebSocket (use globalSocket for reliability)
|
||||
const socket = globalSocket || socketRef.current;
|
||||
if (socket?.connected) {
|
||||
console.log('Sending message via WebSocket:', { conversationId, content: content.trim() });
|
||||
socketRef.current.emit('message', {
|
||||
socket.emit('message', {
|
||||
conversationId,
|
||||
content: content.trim(),
|
||||
});
|
||||
} else {
|
||||
console.error('WebSocket not connected, cannot send message');
|
||||
console.error('WebSocket not connected, cannot send message. Socket state:', socket?.connected);
|
||||
}
|
||||
},
|
||||
[userId, currentConversationId, addMessage],
|
||||
|
|
|
|||
Loading…
Reference in New Issue