メインコンテンツまでスキップ

WebSocket メッセージを変更する

Proxyman Scripting の onWebsocket() で、WebSocket(WS/WSS)メッセージをその場で編集、ドロップ、送信できます。テキストとバイナリの両方向に対応しています。

1. 概要​

Modify WebSocket Messages オプションを有効にすると、スクリプトの onWebsocket() 関数で WebSocket メッセージをその場で変更できます。数行の JavaScript で、次のようなことができます:

  • メッセージを編集します。たとえば、JSON のフィールドを変更したり、テキストを置き換えたりします。
  • メッセージをドロップします。相手側には届きません。
  • クライアントまたはサーバーに新しいメッセージを送信します。
  • 両側で WebSocket を切断します。

WS と WSS の両方に対応しており、クライアントからサーバーへ、サーバーからクライアントへの両方向で動作します。

備考

Modify WebSocket Messages は macOS 版 Proxyman 26.2.0 以降 と Windows/Linux 版 Proxyman 26.1.0 以降 で利用できます。iOS では利用できません。

サーバーは実際の BTC 価格を送信しますが、アプリには $1 が届きます。パスワードを含むメッセージはドロップされ、アプリはスクリプトからの警告を受け取ります。

2. 課題​

チャット、取引、ゲーム、ライブダッシュボードのアプリは、リアルタイムデータの取得に WebSocket を使っています。こうしたアプリのテストは難しく、次のような課題があります:

  • サーバーを制御できません。 サーバーは実際のデータを送信します。価格が 0 の場合やエラーメッセージのような特殊なケースを送信させるには、サーバーのコードを変更する必要があります。
  • 再現しにくいケースがあります。 メッセージの欠落、想定外の応答、接続の切断は、必要なときにめったに起きません。
  • 他のツールではメッセージを変更できません。 Breakpoint と Map Local は HTTP のハンドシェイクを対象としており、その後のメッセージは対象外です。このオプションが無効な場合、onWebsocket() はメッセージを読み取るだけです。

3. メリット​

  • サーバーを変更せずに、アプリが処理すべきすべてのメッセージをテストできます。
  • サーバーの応答をモックできます。sendToClient() でクライアントのメッセージに応答します。サーバーには届きません。
  • 機密データを隠したり、アナリティクスのイベントをサーバーに届く前にブロックしたりできます。
  • 接続の切断を再現して、アプリが再接続する動作をテストできます。
  • ルールに一致する WebSocket だけがスクリプトの処理を待ちます。その他の通信はそのまま流れます。

4. 使い方​

  1. WebSocket の接続をキャプチャします。wss:// の場合は、HTTPS と同様にドメインの SSL Proxying を有効にします。
  2. ws:// または wss:// のフローを右クリックし、Tools → Scripting… を選択します。Proxyman は、URL が入力されたルールと、onWebsocket() を含むスクリプトを作成します。
  3. Request にチェックを入れたまま、Modify WebSocket Messages にチェックを入れます。
  4. onWebsocket() のコードを書き、Save & Activate(⌘S、Windows/Linux では Ctrl+S)を押します。
  5. WebSocket を再接続します。Proxyman は、メッセージごとではなく、WebSocket の接続時にこのオプションを読み取ります。
Modify WebSocket Messages にチェックが入り、onWebsocket() スクリプトが書かれた Proxyman の Script Editor

Script Editor で Modify WebSocket Messages にチェックを入れる

このスクリプトは、サーバーから届く BTC 価格をすべて $1 に変更し、パスワードを含むクライアントのメッセージをドロップします:

function onWebsocket(context, url, request, response, message) {
// Only change text messages. Binary, ping, pong, and close messages pass through
if (message.type !== "text") {
return message;
}

const json = JSON.parse(message.data);

// 1. Server -> client: every BTC price becomes $1
if (message.from === "server" && json.type === "price") {
json.price = 1;
json.note = "edited by Proxyman";
message.data = JSON.stringify(json);
return message;
}

// 2. Client -> server: drop a message with a password, and warn the client
if (message.from === "client" && json.text.includes("password")) {
sendToClient(JSON.stringify({ type: "warning", text: "Proxyman blocked a password" }));
return null;
}

// 3. Everything else: send it as it is
return message;
}

Websocket タブには、編集されたメッセージ、スクリプトが送信したメッセージ、ドロップされたメッセージが表示されます:

ws://localhost:3456/prices のフローと編集された WebSocket メッセージが表示されている Proxyman のメインウィンドウ

Websocket タブで編集・ドロップされたメッセージ

ローカルの WebSocket サーバーを使って自分で試せるステップバイステップのガイドは、英語のブログ記事 How to modify WebSocket messages with Scripting をご覧ください。

5. onWebsocket() の戻り値​

このオプションが有効な場合、Proxyman は onWebsocket() が値を返すまで、テキストとバイナリのメッセージをそれぞれ保留します。返す値によって、次のように動作が決まります:

onWebsocket() での記述結果
return message変更を加えたメッセージを送信します。
return nullメッセージをドロップします。相手側には届きません。
戻り値なし元のメッセージを送信します。
abort()両側で WebSocket を切断します。
sendToClient(data) / sendToServer(data)新しいメッセージを送信します。String はテキストメッセージ、Uint8Array はバイナリメッセージとして送信されます。

message オブジェクトには、次のプロパティがあります:

フィールド説明
message.from"client" または "server"。
message.type"text"、"binary"、"ping"、"pong"、"close" のいずれか。
message.dataメッセージのテキスト。テキストメッセージを編集するには、この値を変更します。
message.rawDataバイナリメッセージのバイト列(Uint8Array)。バイナリメッセージを編集するには、新しい Uint8Array を設定します。
message.closeCode数値。close メッセージでのみ使用でき、たとえば 1000 などです。

その他の引数については、WebSocket での Scripting をご覧ください。

備考

このオプションはデフォルトでオフです。オフの場合、onWebsocket() は従来どおり動作し、メッセージを読み取るだけで、遅延させることはありません。

6. テンプレート​

スクリプトをゼロから書く必要はありません。Script Editor で Templates をクリックし、「websocket」で検索します:

  • Log WebSocket Messages:すべてのメッセージを Console Log に出力します。メッセージを読み取るだけです。
  • Modify JSON WebSocket Messages:サーバーから届く JSON メッセージのフィールドを変更します。
  • Replace Text in WebSocket Messages:両方向のメッセージで、テキストを検索して置換します。
  • Drop WebSocket Messages:正規表現に一致するメッセージをドロップします。たとえば、アナリティクスのイベントなどです。
  • Reply to a WebSocket Message:sendToClient() でクライアントのメッセージに応答します。サーバーには届きません。
  • Simulate a WebSocket Disconnect:数件のメッセージの後に WebSocket を切断します。

テンプレートを使うには Replace をクリックします。Proxyman は必要なチェックボックスも自動で設定します。Modify WebSocket Messages も含まれます。

WebSocket のテンプレートで絞り込まれた、Proxyman の Script Templates シート

Script Editor の WebSocket テンプレート

その他のサンプルは スニペットコード ページにあります。

7. 知っておきたいこと​

  • テキストメッセージとバイナリメッセージは、編集もドロップもできます。Ping、pong、close メッセージは常に送信されます。onWebsocket() でこれらを読み取ることはできますが、戻り値は無視されます。
  • メッセージの種類は変わりません。テキストメッセージをバイナリメッセージに変換することはできません。
  • スクリプトがエラーを投げた場合、または 30 秒以内に戻らない場合、Proxyman は元のメッセージを送信し、エラーを Console Log に出力します。
  • onWebsocket() の外側のコードは接続ごとに 1 回実行されます。そのため、スクリプトの先頭にあるカウンターは、接続ごとのメッセージ数をカウントします。
  • sendToClient() と sendToServer() で送信されたメッセージは、onWebsocket() を再実行しません。そのため、応答するスクリプトが無限ループになることはありません。
  • 同じ WebSocket に一致する、このオプションを有効にしたスクリプトが複数ある場合、順番に実行されます。各スクリプトは、直前のスクリプトが返した値を受け取ります。ドロップされたメッセージは、後続のスクリプトには届きません。
  • 16 MB を超えるメッセージは、スクリプトを通さずにそのまま送信されます。
  • async 関数に対応しているため、onWebsocket() 内で await や $http を使えます。
  • AI エージェントは Proxyman MCP で同じルールを作成できます。create_scripting_rule には modify_websocket_messages: true を指定します。

8. トラブルシューティング​

メッセージが変わらない​

  • Modify WebSocket Messages にチェックを入れ、Save & Activate(⌘S、Windows/Linux では Ctrl+S)を押します。
  • WebSocket を再接続します。このオプションは WebSocket の接続時に読み取られます。
  • Request または Response のどちらかにチェックを入れたままにします。両方のチェックを外したルールは、onWebsocket() を含め、まったく実行されません。
  • メッセージを変更したら、message を返します。戻り値がない場合、Proxyman は元のメッセージを送信します。
  • Script Editor の Console Log を開き、エラーがないか確認します。

Proxyman で WebSocket が表示されない​

お使いのプラットフォームに合わせて WebSocket のガイドに従ってください。多くのアプリやライブラリは、localhost に対してプロキシを経由しません。