웹소켓은 단일 TCP 연결로 전이중 통신 채널을 제공하는 실시간 통신 프로토콜이다.
- 연결지향
- 한번 연결 맺은 뒤 유지
- 양방향 통신
Polling과 비교
클라이언트가 n초 간격으로 서버에게 요청을 보내는 방식인 Polling으로도 충분히 양방향 통신이 가능하다.
그러나 HTTP는 헤더가 무거운 단발성 통신이기에 요청을 지속적으로 보낸다면 서버의 부담이 증가한다.
Long Polling이라는 비교적 서버의 부담을 줄인 방식도 있지만 결국 데이터가 빈번하게 바뀐다면 소용 없다.
이러한 점들을 고려하여 양방향 통신에 최적화된 WebSocket을 사용한다.
동작 방식

WebSocket Handshake
HTTP 업그레이드 헤더를 사용하여 HTTP 프로토콜에서 WebSocket 프로토콜로 변경된다.
요청 본문에는 아래와 같이 Upgrade: websocket을 담아서 보내야 한다.
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: <http://example.com>응답에는 Status Code 101로 Switching Protocols를 담아서 보낸다.
TTP/1.1 101
Switching Protocols Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat왜 독립적인 프로토콜로 관리하지 않는건가?
기존 웹 인프라를 그대로 통과하고 재사용하기 위해 연결할때만 HTTP를 잠시 사용하고 이후에는 WebSocket 프로토콜로 전환하는 구조를 택했다. HTTP Request를 그대로 사용하기 때문에 기존의 80, 443 포트로 접속을 하므로 추가 방화벽을 열지 않고도 양방향 통신이 가능하고, HTTP 규격인 CORS 적용이나 인증 등 과정을 기존과 동일하게 가져갈 수 있는 것이 장점이다.
만약 아래와 같이 별도의 프로토콜로 관리한다면 다음과 같은 문제점이 발생한다.
ws://example.com:12345
- 회사/학교 방화벽이 해당 포트를 막을 수 있음
- Proxy가 알 수 없는 프로토콜을 차단할 수 있음
- Load Balancer가 별도 프로토콜을 지원해야 함
- 웹 서버와 별도의 네트워크 설정 필요
- 브라우저의 기존 HTTP 보안 모델을 재활용하기 어려움 (Cookie, Origin, TLS…)
단점
- WebSocket 연결이 끊어졌을 때의 처리를 직접 구현해야 한다.
- 브라우저 별로 지원하는 웹소켓 버전이 다르며, 모든 브라우저가 WebSocket을 지원하지는 않는다.
- 서버는 수많은 커넥션을 유지해야 하므로 자원을 많이 사용할 수 있다.
- 실시간으로 많은 데이터가 오가지 않는다면 필요 시 연결을 하는 게 비용적으로 이득
