fix: reduce socket ping intervals and remove unreliable auto-delivery status updates in messages gateway

This commit is contained in:
pradeepkumar
2026-04-08 18:39:19 +05:30
parent f468d403e2
commit 1843db79f3

View File

@@ -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}`);