diff --git a/gateway/src/channels/websocket-handler.ts b/gateway/src/channels/websocket-handler.ts index 642a2a83..49aede8b 100644 --- a/gateway/src/channels/websocket-handler.ts +++ b/gateway/src/channels/websocket-handler.ts @@ -312,6 +312,7 @@ export class WebSocketHandler { // Handle disconnection socket.on('close', async (code: number, reason: Buffer) => { + clearInterval(pingInterval); logger.info({ sessionId: authContext.sessionId, code, reason: reason?.toString() }, 'WebSocket disconnected'); // Unregister from event system @@ -334,6 +335,14 @@ export class WebSocketHandler { socket.on('error', (error: any) => { logger.error({ error, sessionId: authContext.sessionId }, 'WebSocket error'); }); + + // Ping every 30 seconds to keep the connection alive through CloudFlare proxy. + // CloudFlare drops idle WebSocket connections after ~100 seconds. + const pingInterval = setInterval(() => { + if (socket.readyState === 1) { // OPEN + socket.ping(); + } + }, 30000); } catch (error) { logger.error({ error }, 'Failed to initialize session'); socket.close(1011, 'Internal server error');