INTEGRITY Dokumentace

Terminálová připojení

Terminálová připojení umožňují uživatelským rozhraním v prohlížeči přímou interakci s shelly sandboxu. Místo spouštění jednotlivých příkazů pomocí exec(), terminálové připojení otevře trvalý obousměrný kanál k shellu bash, stejně jako u SSH nebo lokálního emulátoru terminálu.

Jak fungují připojení k terminálu

Terminálová připojení využívají WebSockety ke streamování syrových bajtů mezi terminálem v prohlížeči (například xterm.js ↗) a proces pseudo-terminálu (PTY) běžící uvnitř kontejneru sandboxu.

Browser (xterm.js) <-- WebSocket --> Worker <-- proxy --> Container PTY (bash)
  1. Prohlížeč odešle vašemu Workeru požadavek na upgrade WebSocketu
  2. Váš Worker volá sandbox.terminal(request), který předává upgrade kontejneru
  3. Kontejner spustí bash shell připojený k PTY
  4. Nezpracované bajty proudí obousměrně: stisky kláves dovnitř, výstup terminálu ven

Toto se zásadně liší od exec():

Ukládání výstupu do vyrovnávací paměti

Kontejner ukládá výstup terminálu do kruhového bufferu. Když se klient odpojí a znovu připojí, server přehraje uložený výstup, takže terminál vypadá nezměněně. To znamená:

Pro zpracování bufferování není potřeba žádný kód na straně klienta, kontejner ho řeší transparentně.

Automatické opětovné připojení

Výpadky sítě jsou v aplikacích běžících v prohlížeči časté. Terminálová spojení to řeší kombinací bufferování na straně serveru (popsáno výše) a opětovného připojení na straně klienta s exponenciálně rostoucí prodlevou.

SandboxAddon pro xterm.js to řeší automaticky. Pokud si vytváříte vlastního klienta, za vlastní logiku opětovného připojení odpovídáte sami: ukládání do vyrovnávací paměti na straně serveru funguje bez ohledu na to, který klient se připojuje. Viz Referenční dokumentace k protokolu WebSocket pro podrobnosti o životním cyklu připojení.

Terminály specifické pro relaci

Každý relace může mít vlastní terminál s nezávislým stavem shellu:

const devSession = await sandbox.createSession({
	id: "dev",
	cwd: "/workspace/frontend",
	env: { NODE_ENV: "development" },
});

const testSession = await sandbox.createSession({
	id: "test",
	cwd: "/workspace",
	env: { NODE_ENV: "test" },
});

// Each session's terminal has its own working directory,
// environment variables, and command history

K terminálu stejné relace se může současně připojit více klientů v prohlížeči. Všichni vidí stejný výstup shellu a mohou odesílat vstup. Tento vzor používejte pro záměrnou spolupráci v rámci jednoho pracovního prostoru, nikoli pro oddělení nezávislých uživatelů.

Protokol WebSocket

Terminálová připojení používají binární rámce WebSocket pro vstup a výstup terminálu (kvůli výkonu) a textové rámce JSON pro řídicí a stavové zprávy (kvůli struktuře). Díky tomu zůstává datová cesta rychlá a zároveň je umožněna strukturovaná komunikace pro operace, jako je změna velikosti terminálu.

Úplnou specifikaci protokolu, včetně životního cyklu připojení a formátů zpráv, najdete v Referenční dokumentace k Terminal API.

Kdy použít terminály a kdy příkazy

Případ použití Přístup
Spuštění příkazu a získání výsledku exec() nebo execStream()
Interaktivní shell pro koncové uživatele terminal()
Dlouhotrvající proces s výstupem v reálném čase startProcess() + streamProcessLogs()
Sdílení terminálu pro spolupráci terminal() se sdílenou relací