Gateway
Protokół mostu
Dlaczego istniał
- Granica bezpieczeństwa: udostępniał niewielką listę dozwolonych operacji zamiast pełnej powierzchni API Gateway.
- Parowanie i tożsamość węzła: przyjmowaniem węzłów zarządzał Gateway, a dostęp był powiązany z tokenem przypisanym do danego węzła.
- Wygodne wykrywanie: węzły mogły wykrywać Gatewaye za pośrednictwem Bonjour w sieci LAN albo łączyć się bezpośrednio przez tailnet.
- WebSocket w local loopback: pełna płaszczyzna sterowania WebSocket pozostawała lokalna, chyba że tunelowano ją przez SSH.
Transport
- TCP, jeden obiekt JSON w każdym wierszu (JSONL).
- Opcjonalny TLS (
bridge.tls.enabled: true). - Domyślnym portem nasłuchiwania był
18790.
Gdy TLS był włączony, rekordy TXT wykrywania zawierały bridgeTls=1 oraz bridgeTlsSha256 jako niepoufną wskazówkę. Rekordy TXT Bonjour/mDNS nie są uwierzytelniane, dlatego klienty nie mogły traktować rozgłaszanego odcisku jako autorytatywnego przypięcia bez dodatkowej weryfikacji poza tym kanałem.
Uzgadnianie połączenia i parowanie
- Klient wysyła
helloz metadanymi węzła i tokenem (jeśli jest już sparowany). - Jeśli nie jest sparowany, Gateway odpowiada
error(NOT_PAIRED/UNAUTHORIZED). - Klient wysyła
pair-request. - Gateway czeka na zatwierdzenie, a następnie wysyła
pair-okihello-ok.
hello-ok zwracało wcześniej serverName; powierzchnie hostowanych pluginów są obecnie ogłaszane przez pluginSurfaceUrls w aktualnym protokole Gateway (Canvas/A2UI używa pluginSurfaceUrls.canvas).
Ramki
Od klienta do Gateway:
req/res: RPC Gateway o ograniczonym zakresie (czat, sesje, konfiguracja, kondycja, wybudzanie głosowe,skills.bins).event: sygnały węzła (transkrypcja głosu, żądanie agenta, subskrypcja czatu, cykl życia wykonania).
Od Gateway do klienta:
invoke/invoke-res: polecenia węzła (canvas.*,camera.*,screen.record,location.get,sms.send).event: aktualizacje czatu dla subskrybowanych sesji.ping/pong: utrzymywanie połączenia.
Egzekwowanie listy dozwolonych operacji znajdowało się w src/gateway/server-bridge.ts (usunięto).
Zdarzenia cyklu życia wykonania
Węzły emitowały exec.finished, aby udostępniać informacje o zakończonej aktywności system.run, mapowanej przez Gateway na zdarzenia systemowe (starsze węzły mogły także emitować exec.started). exec.denied oznaczało odrzuconą próbę system.run jako ostatecznie odrzuconą, bez umieszczania zdarzenia systemowego w kolejce ani wybudzania pracy agenta.
Pola ładunku (wszystkie opcjonalne, o ile nie zaznaczono inaczej):
| Pole | Uwagi |
|---|---|
sessionKey |
Wymagane. Sesja agenta służąca do korelacji zdarzeń oraz, w przypadku exec.finished, dostarczania zdarzeń systemowych. |
runId |
Unikatowy identyfikator wykonania służący do grupowania. |
command |
Surowy lub sformatowany ciąg polecenia. |
exitCode, timedOut, output |
Szczegóły zakończenia (tylko w przypadku ukończenia). |
reason |
Powód odmowy (tylko w przypadku odrzucenia). |
Historyczne użycie sieci tailnet
- Powiązanie mostu z adresem IP sieci tailnet:
bridge.bind: "tailnet"w~/.openclaw/openclaw.json(wyłącznie historycznie;bridge.*nie jest już prawidłową konfiguracją). - Klienty łączyły się za pomocą nazwy MagicDNS lub adresu IP sieci tailnet.
- Bonjour nie działa między sieciami; w przeciwnym razie wymagane było DNS-SD sieci rozległej albo ręczne podanie hosta i portu.
Wersjonowanie
Most niejawnie używał wersji 1, bez negocjowania minimalnej i maksymalnej wersji. Obecne klienty węzłów i operatorów korzystają z protokołu Gateway opartego na WebSocket, który negocjuje zakres wersji protokołu.