# WebSocket

> Proxyman으로 웹 브라우저, iOS 실제 기기와 시뮬레이터, Android, NodeJS 및 Python 서버에서 WebSocket(WS/WSS) 트래픽을 캡처하고 복호화합니다.

## 1. 무엇인가요? {#1-whats-it}

Proxyman은 WebSocket(WS)과 Secure WebSocket(WSS) 트래픽을 캡처하고 간편하게 미리 볼 수 있습니다.

* iOS 실제 기기와 iOS 시뮬레이터의 WS/WSS를 캡처합니다 ([Atlantis 프레임워크](https://github.com/ProxymanApp/atlantis) 필요).
* 웹 브라우저와 Mac 앱에서 WS/WSS를 캡처합니다.
* Android 실제 기기 또는 Android 에뮬레이터에서 WS/WSS를 캡처합니다.
* WebSocket 메시지를 보기 좋게 포맷해 표시합니다.
* All / Sent / Received 메시지를 필터링합니다.
* JSON / Tree Preview / HEX 형식으로 내용을 확인합니다.
* 컬럼 사용자 지정: Frame, Length, Data, Time 등
* 가능한 경우 바이너리 메시지를 JSON으로 자동 디코딩합니다.
* WebSocket 메시지를 Sublime이나 VS Code 같은 외부 편집기에서 열 수 있습니다.
* [Scripting](#7-modify-websocket-messages-with-scripting)으로 WebSocket 메시지를 편집하거나 드롭하고 전송할 수 있습니다(macOS Proxyman 26.2.0 이상, Windows/Linux Proxyman 26.1.0 이상).

## 2. 웹 브라우저에서 WS/WSS 캡처 {#2-capture-wswss-from-web-browsers}

### localhost WebSocket {#localhost-websocket}

[Automatic Setup](https://proxyman.com/docs/ko/automatic-setup/automatic-setup)을 사용하면 Proxyman이 Google Chrome에서 ws://localhost:3000 같은 localhost WebSocket을 캡처할 수 있습니다.

1. **Setup** 메뉴에서 **Automatic Setup…**을 선택합니다.
2. Google Chrome(New Profile 또는 Current Profile)을 선택합니다. 새 Google Chrome 창이 열립니다.
3. 이 창에서 localhost WebSocket 페이지를 엽니다. Proxyman이 해당 WebSocket을 캡처합니다.

### 프로덕션 WebSocket {#production-websocket}

Proxyman은 별도 설정 없이 Google Chrome의 WS/WSS 트래픽을 자동으로 캡처합니다.

1. Proxyman과 Google Chrome을 엽니다.
2. 예를 들어 [https://echo.websocket.org/.ws](https://echo.websocket.org/.ws)에서 WS/WSS 트래픽을 발생시킵니다.
3. Proxyman에서 WS/WSS 데이터를 확인합니다.

### Protobuf 페이로드가 포함된 WebSocket {#websocket-with-protobuf-payload}

Proxyman macOS 6.5.0 이상에서는 WebSocket 메시지에 포함된 Protobuf를 디코딩할 수 있습니다.

1. 먼저 Proxyman에서 WebSocket 트래픽을 캡처할 수 있는지 확인합니다.
2. WebSocket Protobuf 메시지를 마우스 오른쪽 버튼으로 클릭 → **Protobuf** → **Decode Raw Text…** 또는 **Decode with Message Type…**을 선택합니다.

* **Raw mode**: Protobuf desc 파일이 없을 때 유용합니다.
* **Message Type**: Protobuf desc 파일에 정의된 Message Type을 사용합니다.

![바이너리 WebSocket 메시지에서 Protobuf, Decode Raw Text, Decode with Message Type 항목이 보이는 Proxyman 컨텍스트 메뉴](https://proxyman.com/docs/assets/Screenshot%202026-01-30%20at%2015.11.30.jpg)

_Protobuf로 WebSocket 페이로드 디코딩_

## 3. iOS에서 WS/WSS 캡처 {#3-capture-wswss-from-ios}

iOS 앱이 **URLSessionWebSocketTask** 또는 Starscream, SocketRocket 같은 iOS WebSocket 라이브러리를 사용하면 Proxyman이 WS/WSS 트래픽을 캡처하지 못할 수 있습니다.

* **이유**: Apple의 설계 때문입니다. **URLSessionWebSocketTask**는 시스템 HTTP 프록시를 따르지 않습니다. 모든 WS/WSS 트래픽이 인터넷으로 직접 전달되므로 Proxyman이나 Charles Proxy로는 캡처할 수 없습니다.
* 예제 앱: [https://github.com/ProxymanApp/websocket-example-ios-app](https://github.com/ProxymanApp/websocket-example-ios-app)

### ✅ 해결 방법 1 (iOS 17 이상, 권장) {#-solution-1-recommended-for-ios-17-or-later}

1. [iOS 기기](https://proxyman.com/docs/ko/debug-devices/ios-device) 또는 [iOS 시뮬레이터](https://proxyman.com/docs/ko/debug-devices/ios-simulator)의 설정 가이드를 따릅니다. 인증서가 기기에 설치되어 있고 신뢰되어 있는지 확인합니다.
2. Proxyman에서 **Tools**, **Proxy Settings**, **SOCKS Proxy Settings…**를 차례로 선택한 다음 기능을 켭니다. 포트 번호를 메모해 둡니다.
3. Proxyman 메인 창의 툴바에서 현재 IP를 확인합니다.

![IP 192.168.64.4, Proxy Port 9090, Recording, macOS proxy, Network Extension 토글이 표시된 Proxyman 상태 팝오버](https://proxyman.com/docs/assets/proxyman-status-popover.jpg)

_Proxyman의 현재 IP 확인하기_

4. 앱에서 SOCKS 프록시를 설정합니다. 예를 들어 스위치로 디버그 빌드에서만 켜지도록 합니다. 이 설정은 릴리스 빌드에 포함되지 않아야 합니다.

* NWConnection의 경우

```swift
let parameters = webSocketURL.scheme == "wss" ? NWParameters.tls : NWParameters.tcp

let options = NWProtocolWebSocket.Options()
options.autoReplyPing = true

parameters.defaultProtocolStack.applicationProtocols.insert(options, at: 0)

if #available(iOS 17.0, *) {
    let socksv5Proxy = NWEndpoint.hostPort(host: "x.x.x.x", port: 8889) //  Please replace x.x.x.x with a real Proxyman IP
    let config = ProxyConfiguration.init(socksv5Proxy: socksv5Proxy)
    let context = NWParameters.PrivacyContext(description: "my socksv5Proxy")
    context.proxyConfigurations = [config]

    parameters.setPrivacyContext(context)
}

let connection = NWConnection(to: .url(webSocketURL), using: parameters)
connection.start(queue: .main)
```

* URLSession 및 URLSessionWebSocketTask의 경우

```swift
private lazy var urlSession: URLSession = {
    let config = URLSessionConfiguration.default
    if #available(iOS 17.0, *) {
        let socksv5Proxy = NWEndpoint.hostPort(host: "x.x.x.x", port: 8889) //  Please replace x.x.x.x with a real Proxyman IP
        let proxyConfig = ProxyConfiguration.init(socksv5Proxy: socksv5Proxy)
        config.proxyConfigurations = [proxyConfig]
    }

    return URLSession(configuration: config, delegate: nil, delegateQueue: nil)
}()
```

5. 완료 ✅

![iOS 시뮬레이터의 URLSessionWebSocketTask 앱에서 wss://echo.websocket.org 메시지를 캡처하는 Proxyman](https://proxyman.com/docs/assets/Screenshot%202024-11-29%20at%201.17.23%E2%80%AFPM.jpg)

_Proxyman으로 iOS WebSocket 캡처하기_

* 출처: [**FranklinSamboni**](https://github.com/FranklinSamboni) → [https://github.com/ProxymanApp/Proxyman/issues/586#issuecomment-2125082129](https://github.com/ProxymanApp/Proxyman/issues/586#issuecomment-2125082129)
* 튜토리얼: [iOS 시뮬레이터나 기기에서 WebSocket을 가로채고 디버깅하는 방법](https://proxyman.com/posts/2019-10-18-WebSocket-Debugging)

### ✅ 해결 방법 2 {#-solution-2}

Proxyman이 개발한 [Atlantis 프레임워크](https://github.com/ProxymanApp/atlantis#features)를 사용하면 iOS의 WS/WSS **URLSessionWebSocketTask** 트래픽을 캡처할 수 있습니다.

자세한 내용은 [Atlantis WS/WSS 트래픽 가이드](https://github.com/ProxymanApp/atlantis#wswss-traffic)를 참고합니다.

## 4. 웹 브라우저(Chrome, Safari 등)에서 WebSocket 캡처 {#4-capture-websockets-from-your-web-browser-chrome-safari-etc}

* Proxyman은 웹 브라우저의 WS/WSS를 별도 설정 없이 바로 캡처합니다.
* 사용 방법: Google Chrome을 엽니다 → WS/WSS 연결을 만드는 웹사이트에 접속합니다 → Proxyman을 엽니다 → WebSocket 도메인을 찾습니다 → Response 패널에서 해당 도메인에 대해 **Enable SSL Proxying**을 클릭합니다. 브라우저에서 웹사이트를 새로 고칩니다. Proxyman이 WS/WSS를 캡처하고 복호화합니다 ✅

## 5. NodeJS, Golang, Python 서버에서 WebSocket 캡처 {#5-capture-websocket-from-nodejs-golang-python-server}

* Proxyman은 NodeJS, Golang, Python, Ruby 서버의 WS/WSS를 캡처할 수 있습니다.
* 사용 방법: [automatic-setup.md](https://proxyman.com/docs/ko/automatic-setup/automatic-setup)를 참고해 Automatic Setup이 여는 Terminal에서 서버를 시작합니다 → WS/WSS 연결을 만듭니다 → Proxyman이 자동으로 캡처하고 복호화합니다 ✅

## 6. localhost ↔ 프로덕션 WebSocket 매핑 {#6-map-websocket-from-localhost---production}

localhost와 프로덕션 간 WebSocket 트래픽을 매핑할 수 있습니다. 자세한 내용은 [Map Remote 도구](https://proxyman.com/docs/ko/advanced-features/map-remote#74-map-websocket-from-localhost-to-production)를 참고합니다.

## 7. Scripting으로 WebSocket 메시지 수정 {#7-modify-websocket-messages-with-scripting}

macOS용 Proxyman 26.2.0과 Windows/Linux용 Proxyman 26.1.0부터는 몇 줄의 JavaScript로 WebSocket 메시지를 실시간으로 변경할 수 있습니다. Scripting 규칙에서 **Modify WebSocket Messages**를 체크한 다음 `onWebsocket()`을 사용해 다음 작업을 수행할 수 있습니다.

* 양방향 모두에서 텍스트 또는 바이너리 메시지를 편집합니다.
* 메시지를 드롭하면 상대방은 해당 메시지를 받지 못합니다.
* 클라이언트 또는 서버로 새 메시지를 보냅니다.
* WebSocket을 닫아 앱이 재연결되는 방식을 테스트합니다.

```javascript
function onWebsocket(context, url, request, response, message) {
  if (message.from === "server" && message.type === "text") {
    message.data = message.data.replace("staging.example.com", "api.example.com");
  }
  return message;
}
```

- [Modify WebSocket Messages](https://proxyman.com/docs/ko/scripting/modify-websocket-messages)

## 더 알아보기 {#learn-more}

* [Scripting으로 WebSocket 메시지를 수정하는 방법](https://proxyman.com/posts/2026-10-23-modify-websocket-messages-with-scripting)
* [WebSocket을 캡처하고 Protobuf 메시지를 디코딩하는 방법](https://proxyman.com/posts/how-to-capture-websocket-with-protobuf-message)
* [Proxyman vs mitmproxy: Protobuf WebSocket 메시지 디코딩](https://proxyman.com/posts/2026-07-21-Proxyman-vs-mitmproxy-Protobuf-WebSocket)
