Geräte-Routing, Wiederverbindung und Wiederherstellung
Registrierung und Erkennung, die Wiederverbindungsfrist, was ein sich neu verbindendes Telefon neu lädt, wie Timeline-Events nur interessierte Telefone erreichen, Push-Registrierung, und warum das Relay als ein Prozess läuft.
Gegen den Quellcode geprüft am 17. September 2026
Auf dieser Seite
Registrierung und Erkennung
| Client | WebSocket-Header | Gegengeprüft mit |
|---|---|---|
| Desktop | X-Client-Type: desktop | Eine Desktop-Gerätezeile, die dasselbe Konto über HTTP registriert hat. |
| Telefon | X-Client-Type: mobile, dazu X-Target-Desktop-Device-ID für den ausgewählten Desktop | Eine mobile Gerätezeile; der Ziel-Desktop wird bei jeder Registrierung aus Header oder Payload gelesen, nie aus einer gespeicherten Sitzung. |
Wiederverbindungsfrist und Wiederverbindungs-Snapshot
- Desktop-Anfragen-32011 · -32010
Für die geschlossene Verbindung erfasste Anfragen erhalten sofort -32011, „Desktop is reconnecting“, ebenso jede neue Anfrage während der Wartezeit. Danach erhalten neue Anfragen -32010. Einen stummen Socket betrachtet das Relay erst nach 180 Sekunden als geschlossen.
- Wiederverbindungsfristreconnect_timeout
Sie hält nur die Präsenz, und Telefone sehen den Desktop als reconnecting. Nach 90 Sekunden markiert das Relay ihn als offline und sendet device-status disconnected, sofern sich nicht zuvor eine neue Verbindung registriert hat.
- Telefon-Anfragen(user, desktop, id)
Der Eintrag überdauert den Socket des Telefons, sodass eine Antwort, die nach der erneuten Registrierung eintrifft, zugestellt wird. Eine finale Antwort, die in der Lücke eintrifft, wird verworfen, und der Aufruf des Telefons endet an seinem eigenen Timeout.
- Telefon-Leasechat:timeline-interest
An die Verbindung des Telefons gebunden, sodass sie mit dem Socket endet und nichts aus der Lücke aufbewahrt wird. Das Telefon sendet sie erneut, sobald das Relay registered oder resumed antwortet, pingt den Desktop und lädt das neueste Fenster.
Ein Client, der sich mit seinem Resume-Token registriert, durchläuft trotzdem die Protokoll- und Geräteeigentums-Prüfung, und die Antwort lautet resumed und behält die Sitzungs-ID. Auf ein gescheitertes Resume antwortet das Relay mit invalidResume, und der Client registriert sich ohne das Token erneut. Der Relay-Sitzungseintrag hinter dem Token lebt 24 Stunden, wird bei jedem RPC berührt und bei der Abmeldung ungültig gemacht. iOS hält das Token im Schlüsselbund.
Offline-, Reconnecting- und Timeout-Fehler bleiben unterschieden, und nur als retryable markierte Fehler erlauben eine Transportwiederholung. Ein Timeout beschreibt die Antwort, die der Aufrufer nicht bekommen hat. Er sagt nichts darüber, ob die Mutation gelaufen ist, also folgt der Client dem Wiederherstellungspfad der Operation, bevor er neue Arbeit anstößt.
| Status | Bedeutung und nächster Schritt |
|---|---|
| Verbindung wird wiederhergestellt | Das Telefon stellt seine Server-Verbindung wieder her und prüft danach den Desktop erneut. Geben Sie ihm einen Moment. |
| Offline oder getrennt | Prüfen Sie die Desktop-App, den Schlafzustand des Computers, das Konto, die Region und das Netzwerk. |
| Zeitüberschreitung der Anforderung | Die Antwort kam nicht rechtzeitig an. Die Anfrage kann trotzdem gelaufen sein, lesen Sie also den Session-Zustand, bevor Sie eine Mutation wiederholen. |
| Verbunden, aber Verlauf nicht verfügbar | Das Relay funktioniert, und das Lesen des Verlaufs ist fehlgeschlagen. Verwenden Sie die Aktion zum Neuladen in der Timeline. |
Timeline-Events erreichen nur interessierte Telefone
- Interesse-Leasechat:timeline-interest { appSessionId, active }
Vom Telefon für die Session auf seinem Bildschirm gesendet und alle 20 Sekunden erneuert. Das Relay speichert sie pro Telefon und leitet sie nie weiter. Sie enthält keine Timeline-Inhalte.
- Ende der LeaseTIMELINE_INTEREST_TTL = 60 s
Eine Lease endet 60 Sekunden nach ihrer letzten Erneuerung, oder sofort, wenn das Telefon active: false sendet, eine andere Session öffnet oder sein Socket geschlossen oder ersetzt wird. Wartende Updates für dieses Telefon verfallen mit ihr. Einen stummen Socket trennt das Relay erst nach 180 Sekunden, die Lease endet also zuerst.
- Frist auf dem Desktopchat:timeline-interest-updated { expiresAt }
Bei jeder Änderung einer Lease teilt das Relay dem Desktop pro Session mit, ob eine Lease besteht und wann sie endet, aber nie, welches Telefon sie hält. Der Desktop merkt sich diese Frist selbst und serialisiert die Timeline der Session nicht mehr, sobald sie abgelaufen ist.
- Relay-FilterauthorizationGeneration
Wird ausgegeben, wenn eine Session von keiner Lease zu einer wechselt. Jeder Frame muss den aktuellen Wert tragen. Das Relay entfernt ihn und sendet den Frame nur an Telefone, deren Lease beim letzten Senden noch lebt. Für die anderen wird nichts aufbewahrt, daher lädt ein zurückkehrendes Telefon einen Snapshot.
Die Lease ist nach Benutzer, Telefonroute, Ziel-Desktop und Basis-Session geschlüsselt. appSessionId wird getrimmt, auf 1.024 Bytes begrenzt und von einem angehängten skills-agent-Alias befreit. Aktualisierungen an den Desktop tragen außerdem eine Revision und die relayInstanceId, sodass der Desktop veraltete ignoriert und seinen Zustand löscht, wenn sie von einer anderen Instanz kommen.
Ausgehende Timeline-Events warten in einem Koaleszenzpuffer pro Verbindung mit einem ausstehenden Overlay pro Timeline-Schlüssel, einer 512-KiB-Standardbahn mit einer Bahn für Übergrößen darüber und einem Flush alle 250 Millisekunden. Ein gesättigtes Postfach stellt die Verbindungsgeneration ein, sodass das Telefon neu verbindet und abstimmt, statt einen unvollständigen Strom zu erhalten. Der Desktop spiegelt das mit 4 MiB ausstehenden Bytes, 64 regulären Events und 64 koaleszierten Timeline-Schlüsseln pro Verbindung.
Push-Registrierung und Benachrichtigungen
Beide Telefone registrieren ein Push-Token mit PUT api/devices/push-token, während sie angemeldet sind. Der Server sendet genau zwei Arten von Push: die stille desktop_online-Datennachricht, wenn Ihr Desktop sich registriert, mit der beide Apps ihre Verbindung wiederherstellen, bevor Sie sie öffnen, und die sichtbare Meldung, die das Benachrichtigungswerkzeug des Agenten schreibt und die über Desktop, Device-Link, Server und dann APNs oder FCM läuft.
Warum das Relay als ein Prozess läuft
- ProzessspeicherDeviceConnectionManager
Hält jede Verbindungsroute, jeden ausstehenden Anfrage-Eintrag, die Wiederverbindungs-Präsenz und jede Interesse-Lease. RelaySessionStore hält die Resume-Sitzungen. Ein zweiter Prozess sähe nichts davon, darum läuft das Relay als ein einziger Prozess.
- DrainrelayDraining
Unumkehrbar. Ab seinem Beginn weist der Prozess Registrierungen ab. Er wartet höchstens 60 Sekunden auf laufende Routing-Arbeit, löscht dann seinen Speicher, ohne offene Anfragen zu beantworten, und schließt jeden Geräte-Socket.
- Instanz-IDrelayInstanceId
Eine neue UUID pro Prozess, gesendet mit jeder Registrierungsantwort. Telefone ignorieren Präsenz-Events einer anderen Instanz, und der Desktop löscht seinen Interesse-Zustand, wenn Aktualisierungen von einer anderen kommen.
Mit zwei Prozessen hinter einem Load Balancer sähe ein Telefon, dessen Socket auf dem Prozess ohne den Socket seines Desktops gelandet ist, diesen Desktop als offline.
In Produktion gibt es deshalb genau eine Routing-Autorität pro Region. Ein Blue-Green-Deploy startet den neuen Prozess, drainiert den alten und leitet dann den Verkehr zum neuen. Pro Verbindung begrenzt das Relay Frames auf 32 MiB, drosselt mit einem Token-Bucket von 300 Burst und 150 pro Sekunde, pingt alle 30 Sekunden und trennt einen Client nach 180 Sekunden Stille.