본문으로 건너뛰기

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. 사용 방법​

  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 서버와 함께 단계별로 따라 하고 싶다면 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도 포함됩니다.

WebSocket 템플릿으로 필터링된 Proxyman Script Templates 시트

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에 대해서는 프록시를 우회합니다.