Endpoints streaming

Server-Sent Events (SSE) pour les mises a jour de statut des bureaux et les flux d'activite mission control.

3 min de lecture

Vue d'ensemble SSE

Le Bureau utilise les Server-Sent Events (SSE) pour pousser des mises a jour en temps reel vers votre application. Contrairement aux WebSockets, SSE est un protocole unidirectionnel -- le serveur pousse des evenements vers votre client via une connexion HTTP persistante. La connexion se reconnecte automatiquement si elle tombe.

Il y a deux endpoints SSE :

EndpointObjectif
GET /api/desktops/streamChangements de statut des bureaux (demarre, arrete, metriques)
GET /api/mission-control/activity/streamEvenements de taches et d'approbations sur tous les bureaux

Flux de statut des bureaux

GET /api/desktops/stream

Pousse les mises a jour de statut pour tous les bureaux appartenant a l'utilisateur authentifie.

Format des evenements :

{
  "type": "desktop.status",
  "payload": {
    "id": "clx...",
    "name": "my-agent",
    "status": "running",
    "ipAddress": "10.0.3.42",
    "cpu": 23.5,
    "memory": 45.2
  }
}

Types d'evenements :

TypeDescription
desktop.statusLe statut du bureau a change (booting, running, stopped, error)
desktop.metricsChiffres CPU/RAM/disque mis a jour
desktop.agentReadyL'agent a termine son initialisation et est pret pour les taches

Flux d'activite

GET /api/mission-control/activity/stream

Pousse des evenements pour les taches, approbations et activite des bureaux sur votre compte.

Format des evenements :

{
  "type": "task.completed",
  "payload": {
    "taskId": "task_abc123",
    "desktopId": "clx...",
    "status": "done",
    "completedAt": "2026-03-15T10:05:00Z"
  }
}

Voir Surveillance de l'activite pour la liste complete des types d'evenements.

Consommer SSE en JavaScript

// Avec cookie de session (utilisateur connecte)
const stream = new EventSource('/api/desktops/stream');

stream.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log('Evenement:', data.type, data.payload);
};

stream.onerror = (err) => {
  console.log('Erreur SSE, reconnexion automatique:', err);
};

// Nettoyer quand c'est fini
stream.close();

L'API native EventSource ne supporte pas les headers personnalises. Si vous devez utiliser une cle API au lieu d'un cookie de session, passez-la en parametre de requete :

const stream = new EventSource(
  '/api/mission-control/activity/stream?apiKey=lb_k_abc123...'
);

Node.js (base sur fetch)

Pour la consommation cote serveur, utilisez l'API Fetch avec le streaming :

const response = await fetch('https://lebureau.talentai.fr/api/desktops/stream', {
  headers: { 'x-api-key': 'lb_k_abc123...' }
});

const reader = response.body.getReader();
const decoder = new TextDecoder();

while (true) {
  const { done, value } = await reader.read();
  if (done) break;

  const text = decoder.decode(value);
  // Format SSE : "data: {...}\n\n"
  const lines = text.split('\n');
  for (const line of lines) {
    if (line.startsWith('data: ')) {
      const data = JSON.parse(line.slice(6));
      console.log('Evenement:', data.type, data.payload);
    }
  }
}

Python

import requests
import json

response = requests.get(
    'https://lebureau.talentai.fr/api/desktops/stream',
    headers={'x-api-key': 'lb_k_abc123...'},
    stream=True
)

for line in response.iter_lines():
    if line:
        decoded = line.decode('utf-8')
        if decoded.startswith('data: '):
            data = json.loads(decoded[6:])
            print(f"Evenement: {data['type']}", data['payload'])

Reconnexion

SSE a une reconnexion integree. Si la connexion tombe :

  • L'API EventSource du navigateur se reconnecte automatiquement apres un court delai
  • Le serveur envoie un champ id avec chaque evenement -- a la reconnexion, le navigateur envoie Last-Event-ID pour que le serveur puisse rejouer les evenements manques

Pour les clients personnalises (Node.js, Python), implementez la logique de reconnexion dans votre gestionnaire d'erreurs :

function connect() {
  const stream = new EventSource('/api/desktops/stream');
  stream.onerror = () => {
    stream.close();
    setTimeout(connect, 5000); // Reconnexion apres 5 secondes
  };
  stream.onmessage = (event) => {
    // Traiter l'evenement
  };
}
connect();

Notes

  • Les connexions SSE sont legeres. Gardez-les ouvertes pendant toute la duree de votre session de surveillance.
  • Le flux desktop est utile pour des tableaux de bord en direct montrant le statut de la flotte.
  • Le flux d'activite convient aux workflows automatises, comme envoyer une notification Slack quand une tache echoue.
  • Les connexions SSE comptent dans la limite de debit uniquement au moment de la connexion, pas par evenement.