Modify WebSocket Messages
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. 장점
- 서버를 바꾸지 않고도 앱이 처리해야 하는 모든 메시지를 테스트할 수 있습니다.
- 서버 응답을 모킹(Mock)할 수 있습니다.
sendToClient()로 클라이언트의 메시지에 응답하면 서버는 그 메시지를 받지 않습니다. - 서버에 전송되기 전에 민감한 데이터를 가리거나 분석 이벤트를 차단할 수 있습니다.
- 연결이 끊긴 상황을 시뮬레이션해서 앱이 어떻게 다시 연결하는지 테스트할 수 있습니다.
- 규칙과 일치하는 WebSocket만 스크립트를 기다립니다. 나머지 트래픽은 계속 흐릅니다.
4. 사용 방법
- WebSocket 연결을 캡처합니다.
wss://의 경우 HTTPS와 마찬가지로 해당 도메인에 대해 SSL Proxying을 활성화하세요. ws://또는wss://플로우를 우클릭한 뒤 Tools -> **Scripting…**을 선택합니다. Proxyman이 URL이 채워진 규칙과onWebsocket()이 포함된 스크립트를 만듭니다.- Request를 체크한 상태로 두고, Modify WebSocket Messages를 체크합니다.
onWebsocket()코드를 작성한 다음 Save & Activate(⌘S, Windows/Linux에서는 Ctrl+S)를 누릅니다.- WebSocket을 다시 연결합니다. Proxyman은 메시지마다가 아니라 WebSocket이 연결될 때 이 옵션을 읽습니다.

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 탭에는 수정된 메시지, 스크립트가 보낸 메시지, 드롭된 메시지가 표시됩니다:

Websocket 탭에서 수정되고 드롭된 메시지
직접 실행해 볼 수 있는 로컬 WebSocket 서버와 함께 단계별로 따라 하고 싶다면 Scripting으로 WebSocket 메시지를 수정하는 방법을 읽어 보세요.
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 | 숫자입니다(예: 1000). close 메시지에서만 사용할 수 있습니다. |
그 밖의 인수는 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도 포함됩니다.

Script Editor의 WebSocket 템플릿
더 많은 예제는 Snippet Code 페이지에서 확인할 수 있습니다.
7. 알아두면 좋은 점
- 텍스트 메시지와 바이너리 메시지를 수정하고 드롭할 수 있습니다. Ping, pong, close 메시지는 항상 전송됩니다.
onWebsocket()에서 이 메시지를 읽을 수는 있지만, 반환값은 무시됩니다. - 메시지의 타입은 그대로 유지됩니다. 텍스트 메시지를 바이너리 메시지로 바꿀 수는 없습니다.
- 스크립트에서 에러가 발생하거나 30초 안에 반환하지 않으면, Proxyman은 원본 메시지를 보내고 Console Log에 에러를 출력합니다.
onWebsocket()바깥의 코드는 연결마다 한 번씩 실행됩니다. 따라서 스크립트 상단의 카운터는 연결별 메시지 수를 셉니다.sendToClient()와sendToServer()로 보낸 메시지는onWebsocket()을 다시 실행하지 않습니다. 그래서 응답을 보내는 스크립트가 무한 반복에 빠지지 않습니다.- 같은 WebSocket에 이 옵션이 있는 스크립트가 여러 개 일치하면 순서대로 실행됩니다. 각 스크립트는 이전 스크립트가 반환한 값을 받습니다. 드롭된 메시지는 다음 스크립트까지 전달되지 않습니다.
- 16MB보다 큰 메시지는 스크립트를 거치지 않고 그대로 전송됩니다.
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에 대해서는 프록시를 우회합니다.