INTEGRITY Документация

Терминал

Подключайте интерфейсы терминала в браузере к shell песочницы через WebSocket. Серверная часть terminal() метод проксирует WebSocket-соединения к контейнеру, а клиентский SandboxAddon интегрируется с xterm.js для отрисовки терминала.

Серверные методы

terminal()

Проксируйте запрос на обновление до WebSocket, чтобы создать соединение с терминалом.

const response = await sandbox.terminal(request: Request, options?: PtyOptions): Promise<Response>

Параметры:

Возвращает: Promise<Response> : Ответ на обновление до WebSocket

// In your Worker's fetch handler
return await sandbox.terminal(request, { cols: 120, rows: 30 });
// In your Worker's fetch handler
return await sandbox.terminal(request, { cols: 120, rows: 30 });

Работает с обоими сессии по умолчанию и явно созданные сессии:

// Default session
return await sandbox.terminal(request);

// Specific session
const session = await sandbox.getSession("dev");
return await session.terminal(request);
// Default session
return await sandbox.terminal(request);

// Specific session
const session = await sandbox.getSession('dev');
return await session.terminal(request);

Дополнение на стороне клиента

@cloudflare/sandbox/xterm модуль предоставляет SandboxAddon для xterm.js, который обрабатывает соединение WebSocket, переподключение и передачу изменения размера терминала.

SandboxAddon

import { SandboxAddon } from '@cloudflare/sandbox/xterm';

const addon = new SandboxAddon(options: SandboxAddonOptions);

Параметры:

import { Terminal } from "@xterm/xterm";
import { SandboxAddon } from "@cloudflare/sandbox/xterm";

const terminal = new Terminal({ cursorBlink: true });
terminal.open(document.getElementById("terminal"));

const addon = new SandboxAddon({
	getWebSocketUrl: ({ sandboxId, sessionId, origin }) => {
		const params = new URLSearchParams({ id: sandboxId });
		if (sessionId) params.set("session", sessionId);
		return `${origin}/ws/terminal?${params}`;
	},
	onStateChange: (state, error) => {
		console.log(`Terminal ${state}`, error);
	},
});

terminal.loadAddon(addon);
addon.connect({ sandboxId: "my-sandbox" });
import { Terminal } from '@xterm/xterm';
import { SandboxAddon } from '@cloudflare/sandbox/xterm';

const terminal = new Terminal({ cursorBlink: true });
terminal.open(document.getElementById('terminal'));

const addon = new SandboxAddon({
  getWebSocketUrl: ({ sandboxId, sessionId, origin }) => {
    const params = new URLSearchParams({ id: sandboxId });
    if (sessionId) params.set('session', sessionId);
    return `${origin}/ws/terminal?${params}`;
  },
  onStateChange: (state, error) => {
    console.log(`Terminal ${state}`, error);
  }
});

terminal.loadAddon(addon);
addon.connect({ sandboxId: 'my-sandbox' });

connect()

Установите соединение с терминалом песочницы.

addon.connect(target: ConnectionTarget): void

Параметры:

Вызов connect() с новой целью отключается от текущей цели и подключается к новой. Вызов с той же целью при уже установленном соединении не выполняет никаких действий.

disconnect()

Закройте соединение и остановите все попытки переподключения.

addon.disconnect(): void

Свойства

Свойство Тип Описание
state 'disconnected' | 'connecting' | 'connected' Текущее состояние подключения
sandboxId string | undefined Текущий ID песочницы
sessionId string | undefined Текущий ID сессии

Протокол WebSocket

SandboxAddon обрабатывает протокол WebSocket автоматически. Эти детали нужны для создания собственных клиентов терминала без надстройки. Полный пример см. в Подключайтесь без xterm.js.

Жизненный цикл соединения

  1. Клиент открывает WebSocket-соединение с конечной точкой Worker. Задайте binaryType к arraybuffer.
  2. Сервер повторно воспроизводит все буферизованный вывод от предыдущего соединения в виде бинарных кадров. Это может прийти раньше, чем ready сообщение.
  3. Сервер отправляет ready статусное сообщение: терминал теперь принимает ввод.
  4. Бинарные фреймы передаются в обоих направлениях: от клиента поступают нажатия клавиш в кодировке UTF-8, а от сервера поступает вывод терминала (включая ANSI-последовательности).
  5. Если клиент отключается, PTY остаётся активным. При повторном подключении к той же сессии буферизованный вывод воспроизводится заново, поэтому терминал выглядит так же, как прежде.

Управляющие сообщения (от клиента к серверу)

Отправляйте текстовые фреймы JSON, чтобы управлять терминалом.

Изменение размера : обновление размеров терминала (оба cols и rows должен быть положительным):

{ "type": "resize", "cols": 120, "rows": 30 }

Статусные сообщения (от сервера к клиенту)

Сервер отправляет текстовые кадры JSON для событий жизненного цикла.

Готово : PTY инициализирован. Буферизованный вывод (если есть) уже отправлен:

{ "type": "ready" }

Выход : процесс shell завершился:

{ "type": "exit", "code": 0, "signal": "SIGTERM" }

Ошибка : произошла ошибка (например, недопустимое управляющее сообщение или сессия не найдена):

{ "type": "error", "message": "Session not found" }

Типы

interface PtyOptions {
	cols?: number;
	rows?: number;
}

type ConnectionState = "disconnected" | "connecting" | "connected";

interface ConnectionTarget {
	sandboxId: string;
	sessionId?: string;
}

interface SandboxAddonOptions {
	getWebSocketUrl: (params: {
		sandboxId: string;
		sessionId?: string;
		origin: string;
	}) => string;
	reconnect?: boolean;
	onStateChange?: (state: ConnectionState, error?: Error) => void;
}