> ## Documentation Index
> Fetch the complete documentation index at: https://docs.engagefabric.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Real-Time Features

> Enable real-time gamification with EngageFabric WebSockets. Push live leaderboard updates, achievement notifications, and multiplayer events instantly.

EngageFabric provides real-time updates via WebSocket connections, enabling live notifications, leaderboard updates, and multiplayer features.

## How Real-Time Works

```mermaid theme={null}
sequenceDiagram
    participant Client
    participant API
    participant WebSocket
    participant Redis
    Client->>API: POST /events (track action)
    API->>Redis: Publish event
    Redis->>WebSocket: Event notification
    WebSocket->>Client: Real-time update
```

When your application tracks an event via the REST API, the event is published to Redis. The WebSocket server picks up the notification and pushes it to all connected clients in real time.

***

## Connecting

Connect to the WebSocket server with authentication:

```javascript theme={null}
import { io } from 'socket.io-client';

const socket = io('wss://api.engagefabric.com', {
  auth: {
    token: 'your-websocket-jwt'
  },
  transports: ['websocket']
});

socket.on('connect', () => {
  console.log('Connected!');
});

socket.on('disconnect', () => {
  console.log('Disconnected');
});
```

***

## Subscriptions

Subscribe to different channels to receive updates:

### Player Updates

Receive updates when a player's state changes:

```javascript theme={null}
// Subscribe to player updates
socket.emit('subscribe', {
  channel: 'player',
  playerId: 'player-123'
});

// Listen for events
socket.on('xp_updated', (data) => {
  console.log(`New XP: ${data.xp}`);
});

socket.on('level_up', (data) => {
  console.log(`Reached level ${data.newLevel}!`);
  showCelebration();
});

socket.on('quest_progress', (data) => {
  console.log(`Quest ${data.questId}: ${data.progress}/${data.target}`);
});

socket.on('quest_completed', (data) => {
  console.log(`Quest completed: ${data.questName}`);
  showRewards(data.rewards);
});
```

### Leaderboard Updates

Get real-time leaderboard changes:

```javascript theme={null}
socket.emit('subscribe', {
  channel: 'leaderboard',
  leaderboardId: 'weekly-xp'
});

socket.on('leaderboard_updated', (data) => {
  // data.rankings contains updated top players
  updateLeaderboardUI(data.rankings);
});

socket.on('rank_changed', (data) => {
  // Player's rank changed
  console.log(`Your new rank: #${data.rank}`);
});
```

### Lobby Updates

For multiplayer features:

```javascript theme={null}
socket.emit('subscribe', {
  channel: 'lobby',
  lobbyId: 'lobby-abc'
});

socket.on('player_joined', (data) => {
  console.log(`${data.playerName} joined the lobby`);
});

socket.on('player_left', (data) => {
  console.log(`${data.playerName} left the lobby`);
});

socket.on('player_ready', (data) => {
  console.log(`${data.playerName} is ready`);
});

socket.on('lobby_started', (data) => {
  console.log('Game starting!');
  startGame(data);
});
```

### Chat Messages

Real-time chat:

```javascript theme={null}
socket.emit('subscribe', {
  channel: 'chat',
  channelId: 'lobby-abc-chat'
});

socket.on('chat_message', (data) => {
  displayMessage({
    sender: data.senderName,
    content: data.content,
    timestamp: data.timestamp
  });
});
```

***

## Event Types

### Player Events

| Event              | Description                |
| ------------------ | -------------------------- |
| `xp_updated`       | Player's XP changed        |
| `level_up`         | Player reached a new level |
| `currency_updated` | Currency balance changed   |
| `lives_updated`    | Lives count changed        |
| `badge_earned`     | New badge awarded          |
| `quest_progress`   | Quest progress updated     |
| `quest_completed`  | Quest finished             |
| `quest_unlocked`   | New quest available        |

### Leaderboard Events

| Event                 | Description            |
| --------------------- | ---------------------- |
| `leaderboard_updated` | Rankings changed       |
| `rank_changed`        | Player's rank changed  |
| `new_high_score`      | New top score recorded |

### Lobby Events

| Event           | Description                 |
| --------------- | --------------------------- |
| `player_joined` | Player entered lobby        |
| `player_left`   | Player exited lobby         |
| `player_ready`  | Player ready status changed |
| `lobby_started` | Game/session started        |
| `lobby_closed`  | Lobby disbanded             |

### Chat Events

| Event             | Description          |
| ----------------- | -------------------- |
| `chat_message`    | New message received |
| `player_typing`   | Player is typing     |
| `message_deleted` | Message was removed  |

***

## Sending Events

Emit events to the server:

```javascript theme={null}
// Send a chat message
socket.emit('chat:send', {
  channelId: 'lobby-abc-chat',
  content: 'Hello everyone!'
});

// Set ready status in lobby
socket.emit('lobby:ready', {
  lobbyId: 'lobby-abc',
  ready: true
});

// Leave a lobby
socket.emit('lobby:leave', {
  lobbyId: 'lobby-abc'
});
```

***

## Connection Management

### Reconnection

The SDK handles reconnection automatically, but you can customize behavior:

```javascript theme={null}
const socket = io('wss://api.engagefabric.com', {
  auth: { token: 'your-token' },
  reconnection: true,
  reconnectionAttempts: 5,
  reconnectionDelay: 1000,
  reconnectionDelayMax: 5000
});

socket.on('reconnect', (attemptNumber) => {
  console.log(`Reconnected after ${attemptNumber} attempts`);
  // Re-subscribe to channels
  resubscribe();
});
```

### Token Refresh

WebSocket tokens expire after 15 minutes. Implement refresh logic:

```javascript theme={null}
socket.on('token_expired', async () => {
  const newToken = await refreshWebSocketToken();
  socket.auth.token = newToken;
  socket.connect();
});
```

***

## Rate Limiting

WebSocket events are rate-limited to prevent abuse:

| Limit                        | Value |
| ---------------------------- | ----- |
| Events per second            | 10    |
| Subscriptions per connection | 50    |
| Message size                 | 64KB  |

Exceeding limits triggers a warning event:

```javascript theme={null}
socket.on('rate_limited', (data) => {
  console.warn(`Rate limited: ${data.message}`);
});
```

***

## Best Practices

<CardGroup cols={2}>
  <Card title="Unsubscribe when done" icon="xmark">
    Remove subscriptions when leaving screens to reduce bandwidth.
  </Card>

  <Card title="Handle disconnections" icon="plug">
    Implement reconnection logic and re-subscribe after reconnecting.
  </Card>

  <Card title="Batch updates" icon="layer-group">
    Update UI in batches if receiving many events quickly.
  </Card>

  <Card title="Use heartbeats" icon="heart-pulse">
    Monitor connection health with ping/pong events.
  </Card>
</CardGroup>
