Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

ターミナル

最終更新 Markdown で表示Agent セットアップ

WebSocket でブラウザーベースのターミナル UI をサンドボックスのシェルに接続します。サーバー側の terminal() メソッドは WebSocket 接続をコンテナーへプロキシします。クライアント側の SandboxAddon は、ターミナル描画のために xterm.js と連携します。

サーバー側のメソッド

terminal()

WebSocket のアップグレードリクエストをプロキシし、ターミナル接続を作成します。

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

パラメーター:

  • request - ブラウザーからの WebSocket アップグレードリクエスト(Upgrade: websocket ヘッダーが必要です)
  • options(任意):
    • cols - 列数でのターミナル幅(デフォルト: 80
    • rows - 行数でのターミナル高さ(デフォルト: 24

戻り値: 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 モジュールは、xterm.js 向けの SandboxAddon を提供します。WebSocket 接続、再接続、ターミナルリサイズの転送を処理します。

SandboxAddon

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

const addon = new SandboxAddon(options: SandboxAddonOptions);

オプション:

  • getWebSocketUrl(params) - 接続試行ごとに WebSocket URL を組み立てます。受け取る値:
    • sandboxId - 対象のサンドボックス ID
    • sessionId(任意) - 対象のセッション ID
    • origin - window.location から導出した WebSocket オリジン(例: wss://example.com
  • reconnect - 指数バックオフによる自動再接続を有効にします(デフォルト: true
  • onStateChange(state, error?) - 接続状態の変化に対するコールバック
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

パラメーター:

  • target:
    • sandboxId - 接続先のサンドボックス
    • sessionId(任意) - サンドボックス内のセッション

新しい対象で connect() を呼ぶと、現在の対象から切断して新しい対象へ接続します。すでに接続済みの同じ対象で呼んだ場合は何もしません。

disconnect()

接続を閉じ、再接続の試行を止めます。

addon.disconnect(): void

プロパティ

プロパティ 説明
state 'disconnected' | 'connecting' | 'connected' 現在の接続状態
sandboxId string | undefined 現在のサンドボックス ID
sessionId string | undefined 現在のセッション ID

WebSocket プロトコル

SandboxAddon は WebSocket プロトコルを自動で処理します。次の詳細は、アドオンなしで独自のターミナルクライアントを作る場合向けです。完全な例は xterm.js なしで接続する を参照してください。

接続のライフサイクル

  1. クライアントは Worker エンドポイントへ WebSocket を開きます。binaryTypearraybuffer に設定します。
  2. サーバーは、以前の接続の バッファ済み出力 をバイナリフレームとして再送します。ready メッセージより先に届くことがあります。
  3. サーバーは ready ステータスメッセージを送ります。この時点からターミナルは入力を受け付けます。
  4. バイナリフレームは双方向に流れます。クライアントからは UTF-8 のキー入力、サーバーからはターミナル出力(ANSI エスケープシーケンスを含む)です。
  5. クライアントが切断しても、PTY は生き続けます。同じセッションへ再接続するとバッファ済み出力が再送され、ターミナルは変わっていないように見えます。

制御メッセージ(クライアントからサーバー)

ターミナルを制御するには、JSON のテキストフレームを送ります。

リサイズ — ターミナル寸法を更新します(colsrows はどちらも正の値である必要があります):

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

ステータスメッセージ(サーバーからクライアント)

サーバーはライフサイクルイベント向けに JSON のテキストフレームを送ります。

Ready — PTY の初期化が完了しています。バッファ済み出力(ある場合)はすでに送信済みです:

{ "type": "ready" }

Exit — シェルプロセスが終了しました:

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

Error — エラーが起きました(例: 不正な制御メッセージ、またはセッションが見つからない):

{ "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;
}

関連リソース

役に立ちましたか?