feat: Implement message catch-up and retry logic for conversation room joins on socket reconnection.
This commit is contained in:
@@ -489,10 +489,41 @@ export function useMessaging(options: UseMessagingOptions = {}): UseMessagingRet
|
|||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [autoConnect, isAuthenticated]);
|
}, [autoConnect, isAuthenticated]);
|
||||||
|
|
||||||
// Re-join conversation room when reconnecting
|
// Re-join conversation room when reconnecting + fetch missed messages
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isConnected && currentConversationIdRef.current) {
|
if (isConnected && currentConversationIdRef.current) {
|
||||||
socketService.joinConversation(currentConversationIdRef.current);
|
const conversationId = currentConversationIdRef.current;
|
||||||
|
|
||||||
|
const rejoinAndCatchUp = async (attempt = 1) => {
|
||||||
|
// Re-join the room
|
||||||
|
const result = await socketService.joinConversation(conversationId);
|
||||||
|
if (!result.success && attempt < 3 && currentConversationIdRef.current === conversationId) {
|
||||||
|
console.warn(`Room join attempt ${attempt} failed for ${conversationId}, retrying...`);
|
||||||
|
setTimeout(() => rejoinAndCatchUp(attempt + 1), 1000 * attempt);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch recent messages to catch any missed during disconnect
|
||||||
|
if (currentConversationIdRef.current === conversationId) {
|
||||||
|
try {
|
||||||
|
const { messages: recentMessages } = await messagesService.getMessages(conversationId, 1, 20);
|
||||||
|
setMessages((prev) => {
|
||||||
|
const existingIds = new Set(prev.map((m) => m.id));
|
||||||
|
const newMessages = recentMessages.filter((m) => !existingIds.has(m.id));
|
||||||
|
if (newMessages.length === 0) return prev;
|
||||||
|
// Merge and sort by creation date
|
||||||
|
const merged = [...prev, ...newMessages].sort(
|
||||||
|
(a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()
|
||||||
|
);
|
||||||
|
return merged;
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Failed to catch up messages after reconnect:', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
rejoinAndCatchUp();
|
||||||
}
|
}
|
||||||
}, [isConnected]);
|
}, [isConnected]);
|
||||||
|
|
||||||
|
|||||||
@@ -148,6 +148,7 @@ class SocketService {
|
|||||||
this.socket = null;
|
this.socket = null;
|
||||||
}
|
}
|
||||||
this.currentToken = null;
|
this.currentToken = null;
|
||||||
|
this.isConnecting = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
isConnected(): boolean {
|
isConnected(): boolean {
|
||||||
|
|||||||
Reference in New Issue
Block a user