From 1843db79f3461b31744e9363b24965d4504fbf48 Mon Sep 17 00:00:00 2001 From: pradeepkumar Date: Wed, 8 Apr 2026 18:39:19 +0530 Subject: [PATCH] fix: reduce socket ping intervals and remove unreliable auto-delivery status updates in messages gateway --- src/messages/messages.gateway.ts | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/src/messages/messages.gateway.ts b/src/messages/messages.gateway.ts index 2273a05..43abacd 100644 --- a/src/messages/messages.gateway.ts +++ b/src/messages/messages.gateway.ts @@ -29,6 +29,11 @@ interface AuthenticatedSocket extends Socket { credentials: true, }, transports: ['websocket', 'polling'], + // Detect dead connections quickly when a client drops network abruptly + // (e.g. airplane mode). Default is 25s ping + 20s timeout = ~45s to notice. + // 5s ping + 5s timeout = ~10s detection, which keeps presence/ticks honest. + pingInterval: 5000, + pingTimeout: 5000, }) export class MessagesGateway implements OnGatewayConnection, OnGatewayDisconnect { @WebSocketServer() @@ -245,7 +250,13 @@ export class MessagesGateway implements OnGatewayConnection, OnGatewayDisconnect ); // Send directly to the other participant's socket(s) - // This is the primary delivery mechanism — works even if they haven't joined the room + // This is the primary delivery mechanism — works even if they haven't joined the room. + // NOTE: We intentionally do NOT auto-mark as DELIVERED here based on Redis + // presence, because presence can lag behind reality (user turns off network + // but socket hasn't timed out yet). The receiver's client explicitly acks + // delivery via the `message_received` event once it actually receives + // `new_message` — that's the only reliable signal that the receiver's + // device got the payload. try { const participants = await this.messagesService.getConversationParticipants(data.conversationId); if (participants) { @@ -253,22 +264,6 @@ export class MessagesGateway implements OnGatewayConnection, OnGatewayDisconnect ? participants.agentUserId : participants.userId; this.sendToUser(otherUserId, 'new_message', message); - - // Auto-mark as DELIVERED if recipient is online - if (await this.isUserOnline(otherUserId)) { - const deliveredAt = new Date().toISOString(); - await this.messagesService.markMessageDelivered(message.id); - // Update message object so sender gets correct status in callback - message = { ...message, status: 'DELIVERED' as any, deliveredAt } as any; - - const deliveredEvent = { - messageId: message.id, - conversationId: data.conversationId, - deliveredAt, - }; - // Also send event for clients that might have the old status cached - this.sendToUser(client.userId, 'message_delivered', deliveredEvent); - } } } catch (participantError) { this.logger.warn(`Failed to get participants for direct delivery in ${data.conversationId}: ${participantError.message}`);