# Modify WebSocket Messages

> Proxyman Scripting의 onWebsocket으로 WebSocket(WS/WSS) 메시지를 실시간으로 수정, 드롭, 전송하세요. 텍스트와 바이너리 메시지를 양방향 모두에서 다룰 수 있습니다.

## 1. 기능 소개 {#1-whats-it}

**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에서는 사용할 수 없습니다.

<figure class="gb-embed gb-embed--video"><video controls playsinline muted preload="metadata" width="1920" height="1080" src="https://proxyman.com/assets/video/modify-websocket-messages-demo.mp4" aria-label="Proxyman Scripting 규칙이 라이브 WebSocket의 메시지를 수정하고 드롭하는 모습"></video><figcaption><p>서버는 실제 BTC 가격을 보내지만, 앱은 $1을 받습니다. 비밀번호가 포함된 메시지는 드롭되고, 앱은 스크립트로부터 경고를 받습니다.</p></figcaption></figure>

## 2. 해결하려는 문제 {#2-the-problem}

채팅, 트레이딩, 게임, 실시간 대시보드 앱은 실시간 데이터를 받기 위해 WebSocket을 사용합니다. 이런 앱은 테스트하기가 까다롭습니다:

* **서버를 제어할 수 없습니다.** 서버는 실제 데이터를 보냅니다. 가격이 0이거나 에러 메시지 같은 예외 상황을 보내게 하려면 서버 코드를 바꿔야 합니다.
* **일부 상황은 재현하기 어렵습니다.** 메시지 유실, 이상한 응답, 연결 끊김은 필요할 때 좀처럼 발생하지 않습니다.
* **다른 도구로는 메시지를 바꿀 수 없습니다.** [Breakpoint](https://proxyman.com/docs/ko/advanced-features/breakpoint)와 [Map Local](https://proxyman.com/docs/ko/advanced-features/map-local)은 HTTP 핸드셰이크에서 동작하며, 그 이후의 메시지에는 작동하지 않습니다. 이 옵션이 없으면 `onWebsocket()`은 메시지를 읽기만 합니다.

## 3. 장점 {#3-benefits}

* 서버를 바꾸지 않고도 앱이 처리해야 하는 모든 메시지를 테스트할 수 있습니다.
* 서버 응답을 모킹(Mock)할 수 있습니다. `sendToClient()`로 클라이언트의 메시지에 응답하면 서버는 그 메시지를 받지 않습니다.
* 서버에 전송되기 전에 민감한 데이터를 가리거나 분석 이벤트를 차단할 수 있습니다.
* 연결이 끊긴 상황을 시뮬레이션해서 앱이 어떻게 다시 연결하는지 테스트할 수 있습니다.
* 규칙과 일치하는 WebSocket만 스크립트를 기다립니다. 나머지 트래픽은 계속 흐릅니다.

## 4. 사용 방법 {#4-how-to-use-it}

1. WebSocket 연결을 캡처합니다. `wss://`의 경우 HTTPS와 마찬가지로 해당 도메인에 대해 [SSL Proxying](https://proxyman.com/docs/ko/basic-features/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](https://proxyman.com/docs/assets/script-editor-modify-websocket-messages.jpg)

_Script Editor에서 Modify WebSocket Messages를 체크합니다_

이 스크립트는 서버에서 오는 모든 BTC 가격을 $1로 바꾸고, 비밀번호가 포함된 클라이언트의 메시지는 드롭합니다:

```javascript
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 메인 창](https://proxyman.com/docs/assets/websocket-tab-edited-messages.jpg)

_Websocket 탭에서 수정되고 드롭된 메시지_

직접 실행해 볼 수 있는 로컬 WebSocket 서버와 함께 단계별로 따라 하고 싶다면 [Scripting으로 WebSocket 메시지를 수정하는 방법](https://proxyman.com/posts/2026-10-23-modify-websocket-messages-with-scripting)을 읽어 보세요.

## 5. onWebsocket()의 반환값 {#5-what-onwebsocket-returns}

이 옵션이 켜져 있으면 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` | 숫자입니다(예: `1000`). close 메시지에서만 사용할 수 있습니다. |

그 밖의 인수는 [WebSocket에서 Scripting](https://proxyman.com/docs/ko/scripting/script#41-scripting-with-websocket)을 참고하세요.

> **노트:** 이 옵션은 기본적으로 꺼져 있습니다. 옵션이 꺼져 있으면 `onWebsocket()`은 이전과 똑같이 동작합니다. 메시지를 읽기만 하며, 메시지를 지연시키지 않습니다.

## 6. 템플릿 {#6-templates}

처음부터 스크립트를 직접 작성할 필요는 없습니다. 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 시트](https://proxyman.com/docs/assets/websocket-script-templates.jpg)

_Script Editor의 WebSocket 템플릿_

더 많은 예제는 [Snippet Code](https://proxyman.com/docs/ko/scripting/snippet-code#modify-websocket-messages-with-onwebsocket) 페이지에서 확인할 수 있습니다.

## 7. 알아두면 좋은 점 {#7-good-to-know}

* 텍스트 메시지와 바이너리 메시지를 수정하고 드롭할 수 있습니다. Ping, pong, close 메시지는 항상 전송됩니다. `onWebsocket()`에서 이 메시지를 읽을 수는 있지만, 반환값은 무시됩니다.
* 메시지의 타입은 그대로 유지됩니다. 텍스트 메시지를 바이너리 메시지로 바꿀 수는 없습니다.
* 스크립트에서 에러가 발생하거나 30초 안에 반환하지 않으면, Proxyman은 원본 메시지를 보내고 Console Log에 에러를 출력합니다.
* `onWebsocket()` 바깥의 코드는 연결마다 한 번씩 실행됩니다. 따라서 스크립트 상단의 카운터는 연결별 메시지 수를 셉니다.
* `sendToClient()`와 `sendToServer()`로 보낸 메시지는 `onWebsocket()`을 다시 실행하지 않습니다. 그래서 응답을 보내는 스크립트가 무한 반복에 빠지지 않습니다.
* 같은 WebSocket에 이 옵션이 있는 스크립트가 여러 개 일치하면 순서대로 실행됩니다. 각 스크립트는 이전 스크립트가 반환한 값을 받습니다. 드롭된 메시지는 다음 스크립트까지 전달되지 않습니다.
* 16MB보다 큰 메시지는 스크립트를 거치지 않고 그대로 전송됩니다.
* `async` 함수를 지원하므로 `onWebsocket()`에서 `await`와 [$http](https://proxyman.com/docs/ko/scripting/async-await-request)를 사용할 수 있습니다.
* AI 에이전트는 [Proxyman MCP](https://proxyman.com/docs/ko/mcp)로 같은 규칙을 만들 수 있습니다. `create_scripting_rule`에 `modify_websocket_messages: true`를 지정하면 됩니다.

## 8. 문제 해결 {#8-troubleshooting}

### 메시지가 바뀌지 않을 때 {#the-messages-dont-change}

* **Modify WebSocket Messages**를 체크한 다음 **Save & Activate**(⌘S, Windows/Linux에서는 Ctrl+S)를 누르세요.
* WebSocket을 다시 연결하세요. 이 옵션은 WebSocket이 연결될 때 읽힙니다.
* **Request** 또는 **Response**를 체크된 상태로 두세요. 둘 다 체크 해제된 규칙은 `onWebsocket()`을 포함해 아예 실행되지 않습니다.
* 메시지를 바꾼 뒤에는 `message`를 반환하세요. 반환하지 않으면 Proxyman은 원본 메시지를 보냅니다.
* Script Editor에서 Console Log를 열고 에러가 있는지 확인하세요.

### Proxyman에서 WebSocket이 보이지 않을 때 {#i-cant-see-my-websocket-in-proxyman}

사용 중인 플랫폼의 [WebSocket](https://proxyman.com/docs/ko/advanced-features/websocket) 가이드를 따라 하세요. 많은 앱과 라이브러리가 `localhost`에 대해서는 프록시를 우회합니다.
