fix: reduce socket ping intervals and remove unreliable auto-delivery status updates in messages gateway
This commit is contained in:
@@ -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}`);
|
||||
|
||||
Reference in New Issue
Block a user