WebSockets are a powerful communication protocol that enables bidirectional, real-time communication between a client and a server over a single TCP connection
WebSocket은 클라이언트와 서버 간에 단일 TCP 연결을 통해 양방향 실시간 통신이 가능하게 하는 강력한 통신 프로토콜이다. 웹 소켓은 전통적인 API 프로토콜보다 빠르고 요구되는 오버헤드가 적은 "실시간" 애플리케이션 개발이 가능하도록 한다. 웹 소켓은 서버와 클라이언트간의 통신에 이중(duplex) 프로토콜을 사용한다.
실시간 환경이 요구되는 시스템에서 WebSocket은 쉽고 신뢰할 수 있는 요긴한 해결책이다. 계속 변하는 데이터를 실시간으로 보여줘야하는 애플리케이션을 개발하는 경우, WebSocket의 구현을 고려할 수 있다. 다른 방법도 있지만, 이들은 서버에 오버헤드를 증가시키므로 결국 당신은 웹 소켓을 고려하게 될 것이다.
웹 소켓은 클라이언트와 서버간의 연결을 생성해 작동한다. 연결을 시작하기 위해 클라이언트 측에서 update
헤더가 포함된 Get 요청을 전송한다. 이를 통해 서버는 해당 요청이 업그레이드 요청임을 인식하고, 서버가 업그레이드 속성을 지원하는 경우 상태코드 101 Switching Protocols
을 반환하고, 업그레이드 속성을 지원하지 않는 경우 에러 코드를 반환한다. 만약 101
이 아닌 다른 상태코드가 반환되는 경우, 클라이언트 측에서 연결을 종료한다.
웹 소켓은 클라이언트와 서버간의 단일 연결을 생성하고, 그들이 가지는 모든 의사소통에 대해 핸드셰이크(handshakes)를 생성하려고 요구되는 오버헤드가 없다.
handshake 생성을 위한 요청 헤더는 임의의 순서로 전송될 수 있다.
Get
요청을 사용한다. (버전은 1.1
이상이어야 한다.)Host
: 클라이언트와 서버가 서로를 식별할 수 있도록 host 이름이 추가될 수 있다.Sec-WebSocket-Protocol
(OPTIONAL): 클라이언트가 사용할 프로토콜을 지정하기 위해 클라이언트로부터 전송된다.Sec-WebSocket-Version
(OPTIONAL): 클라이언트가 허용하는 하위 프로토콜(웹소켓 프로토콜 위 애플리케이션 래밸에서 사용될 프로토콜)을 나타내기 위해 사용된다.Origin
: WebSocketAPI를 사용하는 스크립트에 의한 웹 브라우저의 무단 교차 출처 사용으로부터 WebSocket 서버를 보호하기 위해 사용된다. 서버는 허용된 origins 에서의 연결만을 허용한다.Sec-WebSocket-Key
: 무작위로 선택된 16바이트 값을 논스(nonce)로 사용해 생성된 base64 인코딩 된 값.이러한 request를 받은 서버는 검증을 거친 후 handshake 요청을 수령 했으며 클라이언트가 연결을 생성할 수 있다는 답장을 반환해야 한다.
example/1
, foo/2
의 프로토콜을 요청했다.Upgrade
로 전송되지 않은 것 처럼 (예: 200 OK
) 응답한다.Upgrade
에 표기하고 101 Switching Protocols
상태를 반환한다.Ugrade
를 사용한 연결 업데이트 메커니즘이 필요하지 않은 것 같다. 따라서 헤당 헤더가 필수적이지 않지만, HTTP 1.1은 해당 헤더가 필요하므로 추가하는게 좋을 것 같다.서버가 수행하는 작업은 다음과 같다.
Sec-WebSocket-key
값을 가져와 전역 고유 식별자(Globally Unique Identifier
)와 결합한 다음, 이 연결 문자열의 SHA-1 헤더를 생성한다.HTTP/1.1 101 Switching Protocols
: 서버는 101 상태 코드로 응답하며, 이외의 상태코드는 오류로 처리되어 핸드셰이크가 완료되지 않았음을 의미한다.Connection
& Upgrade
: HTTP의 업그레이드를 의미한다.Sec-WebSocket-Accept
: 서버가 연결 요청을 수락했는지 여부를 나타낸다. 이 속성의 값은 Sec-WebSocket-key
과 Globally Unique Identifie
를 결합한 해시를 base64로 인코딩한 값을 가진다.Sec-WebSocket-Protocol
(OPTIONAL): 서버가 통신하기로 결정한 프로토콜을 의미한다.WebSocket 클라이언트는 스크립트 페이지에서 이와 같은 응답의 속성값들을 확인한다. 만약 Sec-WebSocket-Accept
속성값이 예상한 값이 아니고, header filed
가 누락되었거나, HTTP 상태코드가 1.1이 아닌경우 연결은 설정되지 않으며, WebSocket 프레임도 전송되지 않는다.
ws
를 위한 기본포트는 80이 사용되고 wss
를 위한 기본 포트는 443이 사용되므로, 포트 구성 요소는 선택사항이다. wss
는 보안 플래그가 설정되어 있고 서버와 클라이언트간 TLS 핸드 셰이크가 수행된 안전한 URI로 사용된다.
웹소켓의 프레임(frame)은 클라이언트와 서버간 교환되는 기본적인 데이터 단위이다. 웹 소켓 프로토콜에서는 연속된 일련의 프레임을 통해 정보가 전달된다. 클라이언트는 프레임을 서버에 보내기 전에 마스크(mask)해야하며 마스크되지 않은 프레임이 서버에 수신되면 서버는 연결을 종료해야 한다.
이 경우, 서버는 1002(protocol error)와 함께 닫기(close) 프레임을 전송할 수 있다.
mask
WebSocket은 보안적인 측면에서 클라이언트의 악의적인 접근을 고려하고, 클라이언트의 브라우저만을 신뢰할 수 있는 상황에서도 네트워크 인프라와 서버를 보호해야 한다는 독특한 구조를 가진다. 마스킹 키는 브라우저에서 각 프레임마다 생성되며 무작위성을 가져 예측이 불가능하다. 이는 프락시 캐시 독점 공격(proxy cache poisoning attack)을 막기 위한 것이며, 악의적 사용자가 전송되는 바이트를 선택하는 것을 막아준다. 마스킹은 웹 소켓 통신 보안의 필수적 요소이며, 권장사항이 아니라 의무적으로 사용되어야 한다.
Http는 각각의 요청에 별도의 연결을 사용한다. 이는 서버로 하여금 모든 요청에 별도의 핸드셰이크를 생성하도록 하므로 서버에게 부담이 될 수 있다. 한번 요청이 완성되면 연결은 종료된다. 반면, 웹 소켓 연결은 어느 쪽에서 중단하지 않는한 연결이 지속된다.
WebSocket 프로토콜은 독립적인 TCP 기반 프로토콜이다. HTTP와의 유일한 연관성은 핸드셰이크가 HTTP 서버에 의해 업그레이드 요청으로 해석된다는 것 뿐이다.
WebSocket은 HTTP와 별개로 동작하며, 자체적으로 TCP 기반의 프로토콜로 설계되어 있다. 즉, 서로 독립적으로 동작하며 서로 다른 프로토콜로 작동하는 것이다. 다만 업그레이드 요청이 HTTP 서버에 의해 해석된다는 것만이 TCP와 HTTP 사이의 유일한 관계이다.
또한 핸드셰이크가 유효한 HTTP 업그레이드 요청이 되도록 하여 서버가 HTTP 서버와 포트를 공유할 수 있도록 설계되었다.
WebSocket 프로토콜은 최소한의 프레이밍(minimal framing)이 있어야 한다는 원칙에 따라 설계되었다. (이는 프로토콜이 스트림 기반이 아니라 프레임 기반으로 동작하며, 유니코드 텍스트와 이진 프레임을 구분할 수 있도록 하는 것이다.)
애플리케이션 계층에 의해 WebSocket위에 계층화되는 메타데이터는, 애플리케이션에 의해 TCP 위에 계층화되는 메타데이터와 동일한 방식으로 작동할 것으로 예상된다.
일반적으로 WebSocket 프롵토콜은 웹소켓 연결에 80포트를 사용하고, TLS(Transport Layer Security, 전송 계층 보안)을 통해 터널링되는 WebSocket 연결에 포트 443을 사용한다.