websocket의 이전 양방향 통신은 한계가 뚜렷했습니다.
HTTP 폴링 (Polling) : 클라이언트가 요청을 보냈지는 일정 주기마다 확인을 하는 작업으로 항상 불필요한 요청과 응답이 있었습니다.
Long Polling : 클라이언트 측에서 요청이 올 때까지 서버는 응답을 지연시키지만 이것 또한 새로운 요청을 보내야 한다는점에서 한계가 있었습니다.
멀티 TCP 연결 : 기존 양방향 통신 방식에서는 클라이언트마다 별도의 TCP를 연결 생성을 하였습니다. 이로인해 서버 부하가 증가하였습니다.
WebSocket의 등장으로 이런 한계점이 개선이 되었습니다.
단 1개의 TCP 연결을 유지하면서 서버와 클라이언트 간의 양방향 통신이 가능해졌습니다.
HTTP 요청-응답 모델을 따르지않고 클라이언트와 서버가 자유롭게 데이터를 주고받게되었습니다.
기존 HTTP 인프라(프록시, 필터링, 인증 등)을 활용하면서 효율적인 통신을 제공합니다.
HTTP 포트 80(일반 ws://)과 443(보안 wss://)을 사용하여 방화벽 우회를 쉽게 할 수 있습니다.
기존 HTTP와 완전히 다른 프로토콜이지만 핸드셰이크 단계에서는 HTTP를 사용하여 연결을 설정할 수 있습니다.
프로토콜은 핸드셰이크와 데이터 전송의 두 부분으로 구성됩니다.
핸드셰이크는 websocket 연결을 설정하는 초기 과정입니다.
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat
핸드셰이크 종료 과정은 Close 프레임을 사용하여 연결을 닫습니다.
현재 제어 프레임에 대해 정의된 opcode 0x8(닫기), 0x9(핑), 0xA(퐁)를 포함합니다.
본문에 종료 이유를 포함할 수 있습니다.
종료 이유는 2바이트 상태 코드와 UTF-8로 인코딩된 데이터가 포함될 수 있습니다.
클라이언트에서 서버로 전송된 닫기 프레임은 다음과 같이 마스킹되어야 합니다.
마스킹란
마스킹 키는 클라이언트가 무작위로 선택한 32비트 값입니다.
클라이언트에서 서버로 보내는 WebSocket 프레임의 페이로드를 변형하여 보안성을 높힙니다.
1000
1000은 정상적인 폐쇄를 나타내며, 이는 다음과 같은 목적을 의미합니다. 연결이 설정되었습니다.1001
1001은 서버와 같이 엔드포인트가 "사라지고 있음"을 나타냅니다. 페이지가 다운되거나 브라우저가 페이지를 벗어났습니다.1002
1002는 엔드포인트가 연결을 종료하고 있음을 나타냅니다. 프로토콜 오류로 인해.1003
1003은 엔드포인트가 연결을 종료하고 있음을 나타냅니다. 수락할 수 없는 데이터 유형(예: 텍스트 데이터만 이해하는 엔드포인트는 이것을 보낼 수 있습니다. 이진 메시지를 수신합니다).
WebSocket은 연결을 위해 초기 핸드셰이크에 HTTP를 사용하지만, 그 이후에는 독립적인 TCP 기반의 통신 프로토콜로 동작합니다.
WebSocket은 TCP 기반 프로토콜입니다.
TCP는 애플리케이션 간에 안전하게 데이터를 주고받는 것을 보장합니다.
기본 포트로는 두가지가 있습니다.
보안 WebSocket(wss://)은 TLS를 사용하여 데이터를 암호화합니다.
이 과정에서 HTTPS와 마찬가지로 프록시 서버를 통과하기 위해 '터널링 연결'이 사용됩니다.
터널링이란?
네트워크 프로토콜의 데이터를 다른 프로토콜의 포맷으로 감싸 전송하는 방식으로,
주로 TLS 같은 보안 연결을 프록시 서버에서 우회하기 위해 사용됩니다.
WebSocket과 HTTP의 관계는 초기 연결 과정에서만 존재합니다.
HTTP는 저 과정에서만 사용하고 그 이후로는 WebSocket 프로토콜을 통해 작동합니다.
WebSocket 연결 종료는 HTTP가 아닌, 자체 프로토콜의 Close 프레임을 통해 처리됩니다.