Node.js WebSocket consumer drops connection on Genesys Cloud Analytics Notification stream

We are implementing a Node.js service to consume real-time analytics notification events from Genesys Cloud and push them to a Kafka topic. The setup uses the ws library to connect to the /api/v2/analytics/realtime/events endpoint. Authentication is handled via a bearer token that we refresh automatically.

The connection establishes successfully, and we receive the initial batch of events. However, after approximately 15 minutes of inactivity on the stream, the connection drops with a 1006 Abnormal Closure. We have implemented a ping/pong keep-alive mechanism in the client, but it seems the server side is not responding to our pings, or perhaps the interval is incorrect.

Here is the relevant snippet:

const ws = new WebSocket(url, {
 headers: { Authorization: `Bearer ${token}` }
});

ws.on('open', () => {
 console.log('Connected to analytics stream');
 // Send ping every 15 seconds
 setInterval(() => {
 if (ws.readyState === WebSocket.OPEN) {
 ws.ping();
 }
 }, 15000);
});

ws.on('close', (code, reason) => {
 console.log(`Connection closed: ${code} ${reason}`);
 reconnect();
});

The logs show the closure code 1006, which typically indicates a network issue or timeout. We are in the Europe/Berlin timezone, so latency to the US-East endpoint might be a factor, but 15 minutes seems too long for a simple timeout. Is there a specific keep-alive requirement for the analytics notification stream that we are missing? Or is this a known issue with the WebSocket implementation in the Node.js environment? We need a reliable stream for our Kafka pipeline.

The 15-minute drop isn’t a Genesys Cloud issue. It’s your load balancer or reverse proxy killing idle TCP connections. WebSocket specs don’t mandate keep-alives from the server, so if no data flows, the intermediate infrastructure assumes the socket is dead.

You need to implement a ping/pong mechanism in your Node.js client. The ws library supports this out of the box. Here is how to configure the client to send pings and expect pongs, which keeps the connection alive through proxies.

const WebSocket = require('ws');

const ws = new WebSocket('wss://api.mypurecloud.com/api/v2/analytics/realtime/events', {
 headers: {
 'Authorization': `Bearer ${accessToken}`,
 'Content-Type': 'application/json'
 }
});

ws.on('open', () => {
 // Send ping every 20 seconds
 setInterval(() => {
 if (ws.readyState === WebSocket.OPEN) {
 ws.ping();
 }
 }, 20000);
});

ws.on('pong', () => {
 // Pong received, connection is healthy
 console.log('WebSocket connection alive');
});

ws.on('close', (code, reason) => {
 console.log(`Connection closed with code ${code}: ${reason}`);
 // Implement reconnection logic here
});

Also check your New Relic transaction traces. You might see a spike in WebSocket errors correlating with these drops. If the proxy is external, you might need to adjust the proxy_read_timeout on Nginx or similar, but the client-side ping is the safest fix since you can’t control all upstream proxies.