Sign inGet started

Verbindungslebenszyklus und Wiederverbindung

Eine Realtime-Verbindung ist ein einzelner WebSocket. Netzwerkwechsel, schlafende Geräte und Infrastruktur-Neustarts können sie schließen. Der Client verbindet sich automatisch wieder, und Ihre App kann den aktuellen Verbindungszustand anzeigen.

Die sechs Zustände

bird.connection.state im Browser-Client und bird.connectionState in Swift und Kotlin ist immer einer dieser Werte (Kotlin verwendet ConnectionState-Konstanten, daher liest sich unavailable als ConnectionState.UNAVAILABLE):
ZustandBedeutung
initializedDer Client existiert und hat noch keinen Socket geöffnet.
connectingEin Socket wird geöffnet oder ist offen und wartet auf den Handshake.
connectedDer Handshake war erfolgreich. Die Verbindung hat eine ID und kann abonnieren.
unavailableDie Verbindung wurde unterbrochen und eine Wiederverbindung ist geplant.
disconnectedSie haben disconnect() aufgerufen. Nichts ist geplant.
failedDer Server hat diese Verbindung abgelehnt. Der Client versucht es nicht erneut.
Binden Sie state_change, um jeden Übergang zu sehen, oder binden Sie einen einzelnen Zustandsnamen, wenn nur einer relevant ist:
import { BirdRealtime } from "@messagebird/realtime";

const bird = new BirdRealtime({ appKey: "your-app-key", region: "us1" });

bird.connection.bind("state_change", ({ previous, current }) => {
  console.log(previous, "->", current);
});

bird.connection.bind("unavailable", () => showReconnectingBanner());
bird.connection.bind("connected", () => hideReconnectingBanner());
Swift und Kotlin verwenden einen Observer für jeden Übergang, verzweigen Sie also auf current. Handler laufen auf der Main Queue in Swift und auf dem Android Main Looper in Kotlin, wenn verfügbar. Übergeben Sie einen deliveryQueue oder Executor, um einen anderen Ausführungskontext zu verwenden.
Ein offener Socket bleibt in connecting, bis der Handshake des Servers eintrifft. Der Handshake setzt bird.connection.connectionId, bevor der Zustand zu connected wechselt, sodass die Autorisierung diese ID signieren kann. Wenn der Handshake die ID auslässt, meldet der Client einen Fehler und schließt den Socket.

Automatische Wiederverbindung

Nach einem unerwarteten Abbruch wartet der Client, bevor er einen neuen Socket öffnet. Die Verzögerung verwendet exponentielles Backoff mit Full Jitter, einer Basis von einer Sekunde und einer Obergrenze von 30 Sekunden. Jeder erfolgreiche Handshake setzt das Backoff zurück.
Der Close-Code entscheidet, welche von drei Reaktionen eintritt:
Close-CodeVerhalten
4000 bis 4099Abgelehnt. Kein erneuter Versuch, Zustand wechselt zu failed.
4200 bis 4299Sofortiger erneuter Versuch.
Alles andereZustand wechselt zu unavailable, dann erneuter Versuch mit Backoff.
Netzwerkfehler nutzen den Backoff-Pfad. Behandeln Sie Ablehnungscodes in Ihrer UI, da diese terminalen Fehler sich nicht automatisch wieder verbinden.

Die Prüfung auf veraltete Verbindungen

Ein Socket kann offen erscheinen, nachdem sein Netzwerkpfad ausgefallen ist. Der Client sendet einen Ping nach dem Activity-Timeout, das standardmäßig 120 Sekunden beträgt, sofern der Handshake keinen anderen Wert liefert. Wenn innerhalb des standardmäßigen Pong-Timeouts von 30 Sekunden kein Pong eintrifft, schließt der Client den Socket mit einem Sofort-Retry-Code.

Was mit Ihren Channels passiert

Subscriptions gehören zur Verbindung, ein Abbruch entfernt sie also. Der Client behält jedes Channel-Objekt, abonniert nach dem nächsten connected-Zustand erneut und behält die vorhandenen Handler bei.
Der Client ruft Ihren authEndpoint erneut auf, für jeden privaten und Presence-Channel mit der neuen Verbindungs-ID. Er kann die alte Signatur nicht wiederverwenden, da diese die vorherige Verbindungs-ID enthält. Nach einem signin()-Aufruf meldet sich der Client außerdem bei jeder neuen Verbindung an und meldet spätere Fehler über signin_error.
bird.connection.bind("signin_error", ({ message }) => {
  console.warn("connection has no identity:", message);
});
Während ein Channel sich neu verbindet, gibt channel.trigger false zurück, ohne das Client-Event zu senden. Prüfen Sie channel.subscribed, oder senden Sie nach bird:subscription_succeeded, das nach jeder erfolgreichen erneuten Subscription feuert.
const room = bird.subscribe("presence-room-1");

room.bind("bird:subscription_succeeded", ({ members }) => {
  renderMembers(members);
});
Realtime spielt keine Events ab, die veröffentlicht wurden, während ein Client getrennt war. Wenn eine Ansicht nach einer Lücke wiederhergestellt werden muss, rufen Sie ihren aktuellen Zustand bei bird:subscription_succeeded ab und wenden Sie spätere Events von dort an.

Absichtliches Trennen

bird.disconnect() schließt den Socket, ohne eine Wiederverbindung zu planen. Verwenden Sie es, wenn ein abgemeldeter oder inaktiver Client keine Live-Daten mehr benötigt. Der Client behält die Channels, sodass ein späteres bird.connect() den Socket wieder öffnet und erneut abonniert.
bird.disconnect(); // state: disconnected, no reconnect
bird.connect(); // reopens and re-subscribes
Auf Mobilgeräten trennen Sie die Verbindung, wenn die relevante View oder Activity stoppt, und verbinden sich erneut, wenn sie fortgesetzt wird. Channel-Objekte und Bindings bleiben verfügbar.

Fehler auf der Verbindung versus Fehler auf einem Channel

Serverfehler, die zu einem einzelnen Channel gehören, treffen auf diesem Channel ein. Eine abgelehnte Subscription ist der häufigste Fall, und ein Authorizer, der 403 zurückgibt, erscheint hier:
room.bind("bird:subscription_error", (err) => {
  console.warn("could not join:", err);
});
Alles, was der Wire keinem Channel zuordnet, trifft stattdessen auf der Verbindung ein:
bird.connection.bind("error", ({ code, message }) => {
  console.warn(code, message);
});

Close-Code 4009 behandeln

Code 4009 liegt im No-Retry-Band, daher wechselt die Verbindung zu failed. Prüfen Sie den Grund, um diese Situationen zu unterscheiden:
  • Ein gekündigtes Mitglied. Ihr Backend hat den Disconnect API für dieses Mitglied aufgerufen, sodass alle seine Verbindungen geschlossen wurden. Siehe Mitgliedverbindungen beenden.
  • Eine Verbindung, die sich nie autorisiert hat. Die App erfordert autorisierte Verbindungen, und diese hat sich nicht rechtzeitig autorisiert. Siehe Autorisierte Verbindungen voraussetzen.
Der Client verbindet sich nicht automatisch wieder, daher entscheidet Ihre App, was als Nächstes passiert:
bird.connection.bind("error", ({ code }) => {
  if (code === 4009) showSignedOutScreen();
});
Ein abgemeldeter Zustand ist angemessen, wenn die Authentifizierung beendet ist. Der Aufruf von bird.connect() startet eine neue Verbindung und wiederholt die Autorisierung, verbinden Sie sich also erst wieder, wenn sich der Autorisierungszustand des Aufrufers ändert.

Nächste Schritte