Zum Inhalt springen

Mit einem Remote-Server verbinden

Jeder Client ist eine Darstellung über einem cc_server, dem die Daten gehören. Der Desktop kann einen in sich selbst ausführen; die Web-App unter app.usectrl.dev nicht, weil ein Browser-Tab keinen Server hosten kann. So oder so richtet diese Anleitung einen Client auf einen Server aus, der woanders läuft — ein kleiner Rechner, eine Cloud-VM, ein Build-Server.

  • Ein laufender cc_server. Hast du noch keinen, siehe Einen Headless-Server betreiben.
  • Entweder die drei Kopplungswerte, die der Server ausgestellt hat — die Server-URL (ws://…/rpc oder wss://…/rpc), eine Geräte-ID und ein Kopplungsschlüssel — oder ein einmaliger Einladungscode von einem Admin des Arbeitsbereichs. Einen Einladungscode einzulösen legt deinen Benutzer an, trägt deine Mitgliedschaft ein und stellt die Zugangsberechtigung dieses Clients für dich aus, sodass du nie eine Geräte-ID oder einen Schlüssel anfasst.

Ein lokaler Server braucht nichts weiter: ws://localhost:9030/rpc funktioniert vom Desktop und vom Browser, weil Browser Loopback als vertrauenswürdige Origin behandeln.

Ein Server auf einer anderen Maschine ist etwas anderes. app.usectrl.dev wird über HTTPS ausgeliefert, deshalb öffnet der Browser nur einen wss://-Socket mit einem Zertifikat, dem er schon vertraut — und cc_server weigert sich von vornherein, eine Adresse außerhalb von Loopback ohne TLS zu binden. Gib ihm eines davon:

  • ein Zertifikat direkt, mit --tls-cert und --tls-key
  • einen TLS-terminierenden Reverse-Proxy davor, den Server mit --insecure gestartet (Klartext hinter dem Proxy, nur in einem vertrauenswürdigen Netz)
  • einen Tunnel oder ein VPN, das das Zertifikat mitliefert — Tailscale, cloudflared oder Ähnliches. Unter Einstellungen → Server → Verbindung und Status liegt die eingebaute Tunnel-Option bei Diesen Server teilen.

Zwei Einstellungen auf der Serverseite übersieht man leicht. Hinter einem Proxy, NAT oder Tunnel setzt du --public-url auf die Adresse, die Clients wirklich anwählen sollen — der Vorgabewert ist die lokale Bind-Adresse, ohne die Option versuchen Clients den falschen Host. Hostest du eine eigene Kopie des Web-Builds, trägst du deren Origin in --allowed-origins ein. Der Vorgabewert ist nur https://app.usectrl.dev; Loopback und native Clients sind immer erlaubt.

Bei einer frischen Installation:

  1. Starte Control Center. Der Bildschirm beim ersten Start fragt Wie soll Control Center laufen?
  2. Statt In dieser App ausführen füllst du die Verbindungsfelder aus: die Server-URL und entweder einen Einladungscode oder eine Geräte-ID und einen Kopplungsschlüssel.
  3. Klicke auf Verbinden. Control Center wählt den Server an und landet im Posteingang des Arbeitsbereichs.

Auf einem Desktop, der schon seinen eigenen Server ausführt:

  1. Öffne Einstellungen → Server → Verbindung und Status.
  2. Klicke auf Server hinzufügen. Gib die Server-URL ein (wss://host:9030/rpc) und entweder einen Einladungscode oder eine Geräte-ID und einen Kopplungsschlüssel. Die Schaltfläche am Ende des URL-Felds entdeckt cc_server-Instanzen in deinem LAN oder Tailnet.
  3. Klicke auf Verbinden, dann auf Wechseln in der Zeile des neuen Servers.

Der Wechsel ist sofort wirksam: Die App baut sich an Ort und Stelle um die neue Sitzung neu auf, ohne Neustart. Schlägt die Verbindung fehl, bleibst du auf dem aktuellen Server und siehst den Fehler. Die Zeile des Servers, auf dem du gerade bist, hat keine Aktion Wechseln; der lokale Server ist die erste Zeile, beschriftet mit In dieser App ausführen.

Nach dem Wechsel besitzt der Desktop keine Datenbank. Jeder Bildschirm liest und schreibt über den entfernten Server per WebSocket.

Der Web-Build ist immer entfernt.

  1. Öffne app.usectrl.dev oder deine eigene Kopie des Web-Builds.
  2. Gib die Server-URL ein und entweder einen Einladungscode oder eine Geräte-ID und einen Kopplungsschlüssel.
  3. Der Client wählt den Server an und zeichnet dieselbe Oberfläche wie der Desktop.

Steht ein Kopplungs-Deep-Link in der URL, sind die Felder vorausgefüllt. Der Kopplungsschlüssel reist im URL-Fragment, das Browser nie an den Server schicken, der die Seite ausliefert. Der statische Host sieht ihn deshalb nie.

Der Web-Client liest und schreibt denselben Server wie der Desktop, aber ein paar Oberflächen brauchen ein natives Fenster oder die eigenen Geräte der Maschine:

  • keine Betriebssystem-Toasts, keine Benachrichtigungstöne und keine Umgebungs-Bannerleiste (die Benachrichtigungszentrale in der App funktioniert weiter)
  • keine Erkennung von Servern im LAN oder Tailnet im Dialog Server hinzufügen
  • kein Artikel-Reader in der App — Newsfeed-Artikel öffnen sich in einem neuen Tab
  • keine Zusammenfassung einer Besprechung erneut laufen lassen und keine abbrechen, die gerade verarbeitet wird

Zwei verhalten sich anders, statt zu fehlen. Die Aufnahme einer Besprechung funktioniert im Browser: Sie erfasst dein Mikrofon plus eine Bildschirmfreigabe mit Audiospur. Im Editor öffnen funktioniert ebenfalls, bittet den Server aber, den Editor auf der Anzeige des Servers zu starten. Auf einem Headless-Host ohne installierte Editoren blendet sich die Schaltfläche deshalb aus.

  • Zeitüberschreitung der Verbindung: Der Server muss vom Client aus erreichbar sein. Prüfe die Bind-Adresse (--bind any), dass der Port offen ist und dass --public-url die Adresse nennt, die der Client wirklich anwählen kann. Über das offene Internet ist TLS Pflicht — ein Klartext-Bind außerhalb von Loopback wird beim Start abgelehnt, außer der Server wurde mit --insecure hinter einem Proxy gestartet.
  • Der Browser verweigert die Verbindung, ein nativer Client funktioniert: Die Origin des Browsers steht nicht auf der Liste --allowed-origins des Servers. Die Vorgabe erlaubt nur https://app.usectrl.dev (plus Loopback).
  • Kopplungsschlüssel abgelehnt: Führe cc_server pair auf dem Server erneut aus, um den Schlüssel dieses Geräts zu rotieren, und gib dann den neuen ein. Ein widerrufenes Gerät findet seine Zugangsdaten schon weg und fällt geschlossen aus; der Widerruf beendet eine laufende Sitzung innerhalb von Sekunden.
  • Falscher Arbeitsbereich: Der Arbeitsbereich steckt in der URL (/workspaces/:workspaceId/…) und reist mit jedem Aufruf mit, deshalb ändert ein Wechsel des Arbeitsbereichs in einem Client nur deine eigene Ansicht. Erreichen kannst du nur Arbeitsbereiche, deren Mitglied du bist — alles andere wird mit “Not a member of this workspace” abgelehnt. Siehe Arbeitsbereiche und Isolation.