SSE Stream Connection

Info

Draft Documentation - This section is currently under review and may be subject to changes.

This endpoint establishes a Server-Sent Events (SSE) connection for receiving real-time notifications and updates. The connection remains open indefinitely, with automatic keep-alive heartbeats every 15 seconds.

Request (GET)

/gateway/sse/{brand_id}/stream

Parameters:

Name In Type Required Description
brand_id path int true The ID of the casino brand.

Headers:

Name Type Required Description
x-auth-token string true Player authentication token.
Accept string true Must be set to text/event-stream.

Response

Status 200 (Connection Established)

Content-Type: text/event-stream; charset=utf-8

Initial Connection Message

Upon successful connection, the server sends an initial “connected” event:

data: {"type":"connected","timestamp":"2025-10-22T14:30:45Z"}

Connected Message Format:

Field Type Description
type string Event type (“connected”).
timestamp string ISO 8601 timestamp in RFC3339 format.

Keep-alive Messages

The server sends keep-alive heartbeats every 15 seconds to maintain the connection:

: keepalive 2025-10-22 14:30:45
data: {"type":"keepalive","timestamp":"2025-10-22 14:30:45"}

Keep-alive Message Format:

Field Type Description
type string Event type (“keepalive”).
timestamp string Timestamp in format “YYYY-MM-DD HH:MM:SS”.

Note: The first line (starting with :) is an SSE comment containing the timestamp. The second line contains the JSON data payload.

Event Messages

When events occur, they are immediately pushed to the client:

data: {"brand_id":1001,"player_id":12345,"event_type":"notification","event_data":{"message_id":"a7f8c934-1b2d-4e5f-9c8a-7d6e5f4a3b2c","event":"bonus_granted","event_details":{"bonus_amount":100,"bonus_type":"welcome"}}}

Event Message Format:

Field Type Description
brand_id int Brand identifier.
player_id int Player identifier.
event_type string Type of event (e.g., “notification”).
event_data object Event-specific data payload (structure varies by type).

Example Connection Flow

1. Client Initiates Connection

const eventSource = new EventSource(
  '/gateway/sse/1001/stream',
  {
    headers: {
      'x-auth-token': 'e74af034-a346-4d5c-be97-f7ed83f373a7'
    }
  }
);

eventSource.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log('Received event:', data);
};

eventSource.onerror = (error) => {
  console.error('SSE connection error:', error);
};

2. Server Sends Connected Event

data: {"type":"connected","timestamp":"2025-10-22T14:30:45Z"}

3. Server Sends Keep-alive (every 15 seconds)

: keepalive 2025-10-22 14:31:00
data: {"type":"keepalive","timestamp":"2025-10-22 14:31:00"}

4. Server Sends Real Event (when published)

data: {"brand_id":1001,"player_id":12345,"event_type":"notification","event_data":{"message_id":"a7f8c934-1b2d-4e5f-9c8a-7d6e5f4a3b2c","event":"bonus_granted","event_details":{"bonus_amount":100,"bonus_type":"welcome","currency":"USD"}}}

Error Responses

Status 400

{
  "status": "error",
  "message": "Bad Request - Invalid brand_id"
}

Status 401

{
  "status": "error",
  "message": "Unauthorized - Invalid or missing authentication token"
}

Status 429

{
  "status": "error",
  "message": "Too Many Requests - Connection limit reached"
}

Note: When the connection limit (SSE_CONNECTION_LIMIT) is reached, new connection attempts will be rejected with a 429 status code.

SSE Error Event (during active connection)

If an error occurs during an active connection, the server may send an error event:

data: {"type":"error","message":"Failed to subscribe to events"}

Connection Management

Connection Limits

  • Default Limit: 50,000 concurrent connections
  • Configuration: Set via SSE_CONNECTION_LIMIT environment variable
  • Behavior: When limit is reached, new connections receive HTTP 429

Connection Termination

Connections can be terminated by:

  1. Client Disconnect: Client closes the connection
  2. Server Error: Internal server error or Redis subscription failure
  3. Network Issue: Network interruption or timeout
  4. Authentication Expiry: Player token expires (requires reconnection)

Reconnection Strategy

Clients should implement automatic reconnection with exponential backoff:

let retryDelay = 1000; // Start with 1 second

eventSource.onerror = () => {
  eventSource.close();

  setTimeout(() => {
    // Reconnect
    eventSource = new EventSource('/gateway/sse/1001/stream', {
      headers: { 'x-auth-token': token }
    });

    // Increase delay for next retry (up to 30 seconds)
    retryDelay = Math.min(retryDelay * 2, 30000);
  }, retryDelay);
};

Implementation Notes

  • Redis Channel Pattern: Events are published to SSE::{brand_id}::{player_id}
  • Event Buffer: Server maintains a 50-event buffer to handle bursts
  • Keep-alive Interval: 15 seconds (prevents connection timeout)
  • HTTP Headers: Connection includes CORS headers and disables buffering
  • Player Context: Player ID is automatically extracted from the authentication token
  • Multi-instance Support: Works across multiple gateway instances via Redis Pub/Sub

Best Practices

  1. Single Connection: Maintain only one SSE connection per player session
  2. Handle Reconnection: Implement automatic reconnection with backoff
  3. Parse Events: Always parse the JSON data payload for event handling
  4. Monitor Keep-alive: Use keep-alive messages to detect connection health
  5. Close on Logout: Explicitly close the SSE connection when player logs out
  6. Error Handling: Implement proper error handling for network issues

See Also