WebSocket 완전 정복 · 3부. 심화: 확장, 인프라, 운영, 보안 · 16편 중 16편 (마지막)
이전 편: 15편 — 보안 체크리스트
15편의 점검 목록까지 통과했다면 WebSocket 하나는 프로토콜부터 운영까지 한 바퀴 돈 셈입니다. 마지막 편은 그 위에 무엇을 얹을지와 WebSocket이 아닌 이웃들을 한 번에 훑고, 시리즈 전체를 요약 일곱 줄과 실습 과제 다섯 개로 닫습니다.
순수 WebSocket 위에 무엇을 얹을까
- Socket.IO는 WebSocket이 아니다: WebSocket을 전송 계층으로 쓰는 자체 프로토콜. 순수 WS 클라이언트로 접속 불가. 자동 재연결, 룸, ack, 폴링 폴백, Redis 어댑터 제공. 양쪽을 통제하고 빨리 만들 때 유리, 표준·다양한 클라이언트가 필요하면 순수 WS.
- STOMP over WebSocket: Spring 진영. SUBSCRIBE/SEND 프레임,
@MessageMapping과 브로커 연동. - GraphQL Subscriptions:
graphql-transport-ws서브프로토콜. - SSE: 단방향이면 더 단순. 일반 HTTP라 프록시·HTTP/2와 잘 맞음. 대시보드 갱신은 SSE로 충분한 경우 많음.
- HTTP/2·HTTP/3 위 WebSocket: RFC 8441, RFC 9220 (Extended CONNECT). 지원 여부는 환경마다 다름.
- WebTransport: HTTP/3(QUIC) 기반. 다중 스트림, 데이터그램, HOL blocking 해소. 게임·미디어에 유망하나 지원 현황 확인 필요.
- WebRTC: 미디어는 P2P/SFU, 시그널링에 흔히 WebSocket 사용.
무엇을 고를 것인가
위 목록에서 WebSocket 자체를 쓸지 말지는 이 글의 물음이 아닙니다. Polling·SSE·WebSocket·WebRTC 가운데 무엇이 맞는지는 네트워크 9장 — 실시간 통신의 선택 가이드가 다루고, 이 시리즈는 WebSocket을 고른 다음의 이야기였습니다. 그래서 여기서 비교하는 것은 WebSocket을 쓰기로 한 뒤 그 위에 무엇을 얹을지 — 순수 ws, Socket.IO, STOMP over WebSocket, GraphQL Subscriptions 네 가지입니다.
| 선택지 | 정체 | 이럴 때 고른다 | 감수할 것 |
|---|---|---|---|
순수 ws | RFC 6455 그대로. 이 시리즈가 다룬 것 | 표준 호환이 필요하거나 다양한 클라이언트가 붙을 때 | 재연결·봉투 형식·ack·룸을 직접 설계한다 (8·9·12편) |
| Socket.IO | WebSocket을 전송 계층으로 쓰는 자체 프로토콜. 자동 재연결·룸·ack·폴링 폴백·Redis 어댑터 내장 | 클라이언트와 서버 양쪽을 통제하고 빨리 만들 때 | 순수 WS 클라이언트로 접속 불가. 폴링으로 시작하면 스티키 세션이 필수가 된다 (12편) |
| STOMP over WebSocket | SUBSCRIBE/SEND 프레임을 얹은 메시징 규약 | Spring 진영에서 @MessageMapping과 브로커 연동을 그대로 쓰고 싶을 때 | WebSocket 위에 프레임 규약이 한 층 더 얹힌다 |
| GraphQL Subscriptions | graphql-transport-ws 서브프로토콜 | 이미 GraphQL을 쓰고 있을 때 | 서브프로토콜이 정한 메시지 형식을 따른다 (협상은 11편) |
질문은 세 개면 충분합니다. 양쪽을 다 통제하는가 — 클라이언트와 서버를 모두 우리가 만든다면 Socket.IO가 주는 재연결·룸·ack가 곧바로 이득이고, 그렇지 않다면 순수 ws가 안전합니다. 다양한 클라이언트가 붙는가 — 브라우저 밖의 언어·기기·다른 팀이 접속한다면 표준 그대로인 순수 ws입니다. 기존 스택이 무엇인가 — Spring이면 STOMP, GraphQL이면 Subscriptions가 이미 있는 도구와 맞물립니다.
어느 쪽을 고르든 그 아래는 같은 WebSocket입니다. 프록시의 Upgrade 헤더와 유휴 타임아웃(14편 — 인프라), 느린 소비자(13편 — 백프레셔와 흐름 제어), 보안 점검(15편 — 보안 체크리스트)은 라이브러리가 대신 겪어 주지 않습니다. 라이브러리가 대신해 주는 것과 여전히 직접 챙겨야 하는 것을 가르는 일이 이 시리즈를 읽은 사람의 몫입니다.
도구
- Chrome DevTools: Network → WS 필터 → Messages 탭
- CLI:
wscat(npm),websocat(Rust) - 부하 테스트: k6(WebSocket 모듈 내장), Artillery. 동시 연결 수와 메시지 처리량은 병목이 다르므로 따로 측정.
시리즈 핵심 요약 일곱 가지
- WebSocket은 HTTP Upgrade로 시작해 TCP 위에서 양방향 메시지를 교환하는 프로토콜이다. (2편 — 프로토콜 개요 · 3편 — 핸드셰이크)
- 프레임은 opcode로 종류를 구분하고, 클라이언트→서버는 캐시 오염 방지를 위해 마스킹한다. (6편 — 프레임 구조)
- 하트비트, 재연결(백오프+지터), seq 기반 복구는 선택이 아니라 필수다. (7편 — 제어 프레임 · 9편 — 재연결 전략)
- 브라우저는 헤더를 못 보내므로 티켓 방식 인증과 Origin 검사가 표준 해법이다. (4편 — 브라우저 API · 10편 — 인증과 인가)
- 연결은 상태이므로 수평 확장에는 Pub/Sub 백플레인이 필요하다. (12편 — 수평 확장)
- 느린 소비자에 대비한 백프레셔 정책을 데이터 성격에 맞게 정한다. (13편 — 백프레셔와 흐름 제어)
- 프록시·LB의 Upgrade 헤더, 유휴 타임아웃, OS 파일 디스크립터 한도를 확인한다. (14편 — 인프라)
실습 과제 다섯 가지
- (기초)
ws없이 Node.jsnet모듈만으로 핸드셰이크와 텍스트 프레임 송수신을 구현하고 브라우저에서 접속해 보기. (3편 — 핸드셰이크 · 6편 — 프레임 구조) - (중급) 8편의 봉투 형식 + 9편의 재연결 클래스로 채팅 앱 제작. 서버 재시작 후 메시지 누락 없이 이어지는지 확인.
- (중급) 티켓 방식 인증 적용, 다른 Origin 페이지에서 접속이 거부되는지 테스트. (10편 — 인증과 인가)
- (심화) 서버 두 대를 Nginx 뒤에 두고 Redis로 연결. 서로 다른 서버의 클라이언트 간 채팅 확인 후, 한 대 종료 시 재분배 관찰. (12편 — 수평 확장 · 14편 — 인프라)
- (심화) k6로 1만 연결 부하. 메모리, 파일 디스크립터, 이벤트 루프 지연 측정 후 어느 한계에 먼저 도달하는지 기록. (14편 — 인프라)
참고 문서
- RFC 6455 — The WebSocket Protocol
- RFC 7692 — Compression Extensions for WebSocket (permessage-deflate)
- RFC 8441 — Bootstrapping WebSockets with HTTP/2
- RFC 9220 — Bootstrapping WebSockets with HTTP/3
- MDN — WebSocket API
ws라이브러리 README
더 깊이
- 풀스택 개발자를 위한 네트워크 9장 — 실시간 통신: Polling, SSE, WebSocket, WebRTC: 이 시리즈가 출발점으로 삼은 "WebSocket을 고른다"는 결정 자체를 다시 묻는 글입니다. 네 선택지를 요구사항 기준으로 비교합니다.
- 풀스택 개발자를 위한 네트워크 15장 — 정리: 풀스택 개발자 네트워크 체크리스트: 네트워크 시리즈 전체의 점검 목록입니다. 이 시리즈의 15편이 WebSocket 한 프로토콜을 다뤘다면, 그쪽은 개념·설계·운영을 넓게 훑습니다.