본문으로 건너뛰기
김신건의 로그

[Network] WebSocket: HTTP upgrade, frame, ping/pong

· 수정 · 📖 약 2분 · 536자/단어 #websocket #network #realtime #backend
WebSocket, WS, WSS, RFC 6455, Upgrade: websocket, websocket frame

정의

WebSocket (RFC 6455) 은 HTTP/1.1 upgrade 로 시작 하는 양방향 영속 메시지 채널. 한 TCP 위에서 서버 ↔ 클라이언트 임의 시점 push 가능.

활용: 실시간 채팅, 트레이딩 시세, 게임, 알림, 공동 편집, 라이브 대시보드.

Handshake: HTTP Upgrade

sequenceDiagram
    autonumber
    participant C as Client
    participant S as Server

    C->>S: GET /chat HTTP/1.1<br/>Upgrade: websocket<br/>Connection: Upgrade<br/>Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==<br/>Sec-WebSocket-Version: 13
    S-->>C: 101 Switching Protocols<br/>Upgrade: websocket<br/>Connection: Upgrade<br/>Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
    Note over C,S: 이후 같은 TCP 위에서<br/>WS frame 양방향 교환
    C->>S: WS frame (text/binary)
    S->>C: WS frame (서버 push)

Sec-WebSocket-Accept = base64(SHA-1(key + “258EAFA5-E914-47DA-95CA-C5AB0DC85B11”)). handshake 무결성 검증.

Frame 구조

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len |    Extended payload length    |
|I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
|N|V|V|V|       |S|             |   (if payload len == 126/127) |
| |1|2|3|       |K|             |                               |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
|     Extended payload length continued, if payload len == 127  |
+ - - - - - - - - - - - - - - - +-------------------------------+
|                               |Masking-key, if MASK set to 1  |
+-------------------------------+-------------------------------+
|    Masking-key (continued)    |          Payload Data         |
+-------------------------------- - - - - - - - - - - - - - - - +
:                     Payload Data continued ...                :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
|                     Payload Data continued ...                |
+---------------------------------------------------------------+
opcode의미
0x0Continuation (다음 frame 이어짐)
0x1Text (UTF-8)
0x2Binary
0x8Close
0x9Ping
0xAPong

IMPORTANT

클라이언트 → 서버 frame 은 반드시 MASK (XOR with 4-byte key). cache poisoning 방지 목적. 서버 → 클라이언트 는 unmask.

Ping / Pong (keep-alive)

sequenceDiagram
    loop 30초마다
        S->>C: PING (opcode 0x9)
        C-->>S: PONG (opcode 0xA, payload 동일)
    end
    Note over S: 90초 PONG 없음 → close

TIP

NAT timeout 또는 프록시 idle close 를 방지. 보통 30~60초 간격. NAT 일반 idle timeout 이 60s 이므로.

Subprotocol

Sec-WebSocket-Protocol: chat, soap

서버가 선택해서 응답 헤더에 같은 것 반환. 클라이언트가 프로토콜 분기 (예: GraphQL over WS, MQTT over WS).

WSS (WebSocket Secure)

wss:// = WebSocket over TLS. 운영에서는 거의 필수:

  • 일부 ISP / 프록시가 ws:// 를 차단
  • mixed content (https 페이지에서 ws://) 브라우저 거부
  • 대부분의 WAF / LB 가 wss 에 최적화

흔한 함정

WARNING

  1. Idle timeout 사고 = ALB/nginx 의 60초 default 가 silent close. PING/PONG 간격 < idle timeout 필수.
  2. Backpressure 부재 = 서버가 빠르게 send → 클라이언트 buffer 폭발. application 레벨 flow control (ACK / credit) 필요.
  3. Sticky session 필요 = 같은 사용자가 같은 노드. LB cookie 또는 IP hash. 또는 connection ID + Redis pub/sub 으로 fan-out.
  4. CORS 가 WebSocket 에 그대로 적용 안 됨 = Origin 헤더는 수동 검증. 미검증 시 CSRF.

패턴: 채팅 fan-out

flowchart LR
    C1[Client 1] -->|WS| N1[Server Node A]
    C2[Client 2] -->|WS| N2[Server Node B]
    C3[Client 3] -->|WS| N1
    N1 -->|Redis PUB| Redis[(Redis Pub/Sub)]
    N2 -->|Redis SUB| Redis
    N1 -->|Redis SUB| Redis
    Redis -->|fan-out| N1 & N2

자세한 fan-out 은 Redis Pub Sub vs Streams 참고.

대안 비교

기술방향영속성사용
WebSocket양방향영속채팅, 게임, 트레이딩
SSE서버 → 클라이언트영속알림, 라이브 피드
Long polling양방향 (서버에서 hold)짧음legacy fallback
HTTP/2 server push폐기--
WebRTC DataChannel양방향 P2P영속게임, 파일

자세한 건 realtime-comparison 참고.

관련 위키

이 글의 용어 (6개)
[Network] HTTP/1.1: keep-alive, pipelining, chunked transfernetwork
정의 HTTP/1.1 (1997, RFC 9112 으로 재정리) 는 텍스트 기반 stateless request/response 프로토콜. 2026 시점에도 대부분의 트래픽이 H…
[Network] Realtime 전송 비교: Polling / SSE / WebSocket / WebRTCnetwork
정의 실시간 (서버 → 클라이언트) 데이터 전송 의 7가지 패턴 비교. 결정 트리 7가지 비교 | 패턴 | 방향 | 영속 | 프로토콜 | 사용 | |---|---|---|---|…
[Redis] Pub/Sub vs Streams: 휘발 신호 vs 영속 로그database-internals
정의 - Pub/Sub ( / ): 지금 듣고 있는 구독자 에게만 메시지가 전달되는 휘발성 신호. 영속 없음, ACK 없음. fan-out. - Streams ( / / / ):…
SIMDalgorithm
정의 SIMD (Single Instruction Multiple Data) 는 한 명령어로 여러 데이터 를 병렬 처리하는 CPU 기능. x86 의 SSE / AVX / AVX2…
Sticky Sessionconcurrency
정의 Sticky Session (= Session Affinity)은 로드밸런서가 같은 클라이언트의 요청을 항상 같은 백엔드 서버로 라우팅하도록 하는 동작이다. 서버, 즉 세션…
TCPnetwork
정의 TCP (Transmission Control Protocol)는 신뢰성 있는 연결 지향 전송 계층 프로토콜이다. RFC 9293 으로 정의되어 있다. HTTP/1.1·2,…

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기