Zum Hauptinhalt springen

Server-Sent Events

Der SSE-v2-Endpoint streamt alle Vorgangs-, Tour- und Activity-Ereignisse in Echtzeit über /api/v2/events/stream. Alle Events werden über eine einzige authentifizierte Server-Sent-Events-Verbindung mit Tenant-bewusster Filterung ausgeliefert.

Endpoint im Überblick​

  • GET /api/v2/events/stream
  • Erfordert Authorization: Bearer <JWT>
  • Response-Media-Type ist text/event-stream
  • Optionaler Query-Parameter: lastEventId – setzt den Stream ab einer im Cache befindlichen Event-ID fort (siehe Replay-Abschnitt)
  • Statuscodes:
    • 200 – Live-SSE-Stream (jedes event: ist ein konkreter BaseEventDTO-Untertyp)
    • 401 – nicht authentifiziert (ErrorDTO)
    • 429 – mehr als die erlaubte Anzahl gleichzeitiger SSE-Verbindungen pro Benutzer (Standard 5)
    • 500 – allgemeiner Server-Fehler

Verbindung aufbauen​

import { fetchEventSource } from '@microsoft/fetch-event-source';

await fetchEventSource('https://api.tourfold.com/api/v2/events/stream', {
headers: { Authorization: `Bearer ${token}` },
onmessage(event) {
console.log('event received', event.event, JSON.parse(event.data));
},
});

Wiederaufnahme mit lastEventId​

Alle Events enthalten einen id:-Header, der eventId spiegelt. Speichern Sie die jeweils letzte ID clientseitig und senden Sie sie beim Reconnect mit, um verpasste Daten aus der In-Memory-History (ca. die letzten 10.000 Events pro Node) wiederzugeben. Wenn Sie die vorherige ID in lastEventId gespeichert haben:

await fetchEventSource(
`https://api.tourfold.com/api/v2/events/stream?lastEventId=${encodeURIComponent(lastEventId ?? '')}`,
{ headers: { Authorization: `Bearer ${token}` }, onmessage: handleEvent }
);

Es wird kein Fehler ausgegeben, wenn eine falsche lastEventId übergeben wird oder eine eventId so alt ist, dass sie nicht mehr im Speicher liegt. Nur die letzten 100 Events bleiben erhalten und können wieder aufgenommen werden – als Schutz gegen kurze Netzwerkstörungen. Diese API garantiert nicht, dass während einer Trennung keine Events verloren gehen.

Event-Format​

Jede SSE-Nachricht sieht folgendermaßen aus:

event: CASE_CREATED:V1
id: 018fb1ba-15c1-7f2a-9f2d-2f2b0b8f3b1a
data: {"kind":"CASE_CREATED:V1","eventId":"018fb1ba-15c1-7f2a-9f2d-2f2b0b8f3b1a","timestamp":"2024-03-22T10:41:09.123Z","tenantId":"...","caseId":"...","caseData":{...}}

Häufige Envelope-Felder:

  • eventId / id: – serverseitig generierte UUIDv7 zur Reihenfolgenbildung.
  • timestamp – Zeitpunkt, zu dem das Backend die Änderung aufgezeichnet hat (UTC).
  • tenantId – stimmt stets mit dem Tenant des Abonnenten überein; Events anderer Tenants werden gefiltert.
  • businessId – komfortabler String, abgeleitet aus caseId, tourId, vehicleId usw.
  • kind – Diskriminator und SSE-event:-Name.

Event-Arten​

Event-ArtWann sie ausgelöst wird
CASE_CREATED:V1Vorgang wird erstmals persistiert
CASE_UPDATED:V1Beliebige Aktualisierung eines bestehenden Vorgangs
CASE_ACTION:V1 <strong style={{color:'#c62828'}}>DEPRECATEDVeraltetes Workflow-Action-Event; verwenden Sie stattdessen andere Vorgangs-Events
CASE_COMMENT_ADDED:V1Neuer Kommentar wurde an einem Vorgang erfasst
CASE_EXTERNAL_ID_UPDATED:V1Externe Referenz (z. B. ERP/CRM) hat sich geändert
TOUR_CREATED:V1 / TOUR_UPDATED:V1 / TOUR_DELETED:V1Tour-Lebenszyklus-Events
VEHICLE_LOCATION_UPDATED:V1 <strong style={{color:'#c62828'}}>DEPRECATEDGPS-Position eines Fahrzeugs wurde aktualisiert
AREA_WAITING_TIME_UPDATED:V1Operative Wartezeit für einen Bereich ändert sich
HEARTBEAT:V1Synthetischer Heartbeat, ca. alle 30 s ausgegeben

Verbindungs-Lebenszyklus, Limits und Fehler​

  • Timeouts – Alle SSE-Verbindungen werden serverseitig automatisch alle 90 Sekunden geschlossen, sodass der Client neu verbinden muss. Dieses kürzere Timeout sorgt dafür, dass tote Verbindungen (z. B. von Proxies oder Load Balancern getrennt) schnell erkannt und bereinigt werden. Der Client baut die Verbindung mit aktuellem JWT-Token automatisch wieder auf.
  • Heartbeats – Werden ca. alle 30 Sekunden gesendet. Damit erkennen Sie inaktive Verbindungen ohne Anwendungsdaten. Ignorieren Sie sie, wenn Sie nur an fachlichen Events interessiert sind. Sendet das Backend keinen Heartbeat (Hinweis auf eine tote Verbindung), wird die Verbindung automatisch aufgeräumt.
  • Bereinigung inaktiver Verbindungen – Der Server prüft periodisch Verbindungen, die keine Daten (einschließlich Heartbeats) erfolgreich gesendet haben, und räumt sie automatisch auf. Damit werden Ressourcenlecks durch Netzwerkfehler vermieden.
  • Rate Limiting – Der Server erzwingt sowohl Durchsatz-Limits (gegen Überflutung) als auch eine pro Benutzer geltende Obergrenze gleichzeitiger Verbindungen (Standard 5). Schließen Sie ungenutzte Browser-Tabs oder EventSource-Instanzen, um unter dem Limit zu bleiben.
  • Replay-Cache – Nur die jüngsten ca. 100 Events werden für lastEventId-Aufholungen vorgehalten. Reconnects nach diesem Zeitfenster erfordern einen manuellen Re-Sync über die REST-APIs.

Fehler-Bodies folgen ErrorDTO. Siehe den Leitfaden zur Fehlerbehandlung.