웹소켓은 하나의 TCP접속에 전이중 통신 채널을 제공하는 컴퓨터 통신 프로토콜이다 - wikipedia
웹소켓이란 서버와 클라이언트간 실시간 양방향 통신을 가능하게 하는 프로토콜의 한 종류로, 서버에서 클라이언트로 데이터를 전송하기 위해서 클라이언트에서 먼저 요청을 보내야만 하는 HTTP의 단점을 보완하고자 등장한 프로토콜이다.
위에서 말한 것 처럼 웹소켓은 HTTP와 달리 실시간 양방향 통신을 가능하게 하는 프로토콜이기 때문에, 웹소켓의 가장 큰 특징은 전이중 통신(Full Duplex)과 실시간 네트워킹(Realtime Networking)이다.
웹소켓이 등장하기 전 HTTP위에서 실시간 양방향 통신을 가능하게 하던 방법은 다음과 같다.
클라이언트에서 짧은 주기로 서버에 지속적으로 요청을 보내 실시간과 유사한 성능을 내는 방식이다.
Polling방식의 통신은 HTTP를 사용하기 때문에 요청을 보낼때마다 TCP Connection이 생기고, HTTP자체의 헤더크기가 크기 때문에 오버헤드가 크다는 단점이 있다.
또한 짧은 요청주기로 실시간인것처럼 동작할 뿐이지 실제 실시간으로 데이터를 받아오는것이 아니기 때문에, 주식차트과 같이 실시간성이 중요한 서비스에서는 사용하기 어렵다
Polling과 유사하게 일정 주기마다 서버로 요청을 보내지만, 서버에서 특정 이벤트나 타임아웃이 발생했을 때에만 응답을 하는 방식이다.
Polling과 비교했을 때 Long Polling의 장점은 서버에서 이벤트가 발생하면 응답하기 때문에 실시간 통신이 가능하다는 점이다.
하지만 Long Polling역시 HTTP를 사용하고 일정 주기마다 지속적으로 요청을 보내기 때문에 Polling과 동일한 문제점이 존재한다.
통신 시작시 클라이언트에서 한번 요청을 보내면, 서버에서 이벤트가 발생할 때마다 응답을 보내지만, 응답을 완료시키지 않고 연결을 계속 유지하는 방식이다.
클라이언트에서 요청을 한번만 보내면 되기 때문에 요청을 지속적으로 보내는 Polling이나 Long Polling보다 효율적이지만, 연결 시간이 길어질수록 Connection의 유효성을 관리하는 비용이 발생한다.
또한 HTTP기반 통신방법이기 떄문에 통신시 주고받는 헤더가 불필요하게 크다는 단점이 있다.
서버와 클라이언트가 웹소켓을 통해 통신하기 위해서는 위의 세 과정을 따른다.
먼저 서버와 클라이언트가 웹소켓 채널의 연결을 맺기 위해서는 HTTP를 사용하여 Handshaking을 한다. 구체적인 과정은 아래와 같다.
GET /chat HTTP/1.1
Host: localhost:8080
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://localhost:9000
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat
위와 같은 과정을 통해 TCP/IP기반 웹소켓 채널이 연결되면 일정시간 후 HTTP연결은 자동으로 끊어진다. 이때 웹소켓 채널이 사용하는 포트는 http연결에 사용되는 포트(80, 443)를 그대로 사용한다.
Handshake이후 서버와 클라이언트는 ws://나 wss://로 시작하는 웹소켓 프로토콜을 사용하여 데이터를 주고받을 수 있다. 이때부터 데이터는 패킷이 아닌 메시지라는 단위로 전달된다.
웹소켓의 데이터 전송 단위인 메세지는 여러 프레임이 모여서 만들어진 논리적인 단위로, 프레임은 2계층(데이터링크 계층)의 데이터 전송단위이다. 프레임은 작은 헤더와 페이로드로 구성되어 있기 때문에, 웹소켓에서는 HTTP를 사용할 때보다 전송되는 메세지의 헤더 크기가 작다는 장점이 있다.
하지만 웹소켓이 전달하는 메세지는 단순히 텍스트 or 바이너리 데이터이기 때문에 정해진 메세지 형식이 없다. 따라서 대부분의 경우 웹소켓을 사용할 때에는 STOMP와 같은 sub-protocol을 사용하여 메세지의 형식을 약속하여 사용한다.
구현의 복잡성 : 웹소켓은 HTTP와 달리 Stateful Protocol이기 떄문에 서버와 클라이언트간의 연결을 유지하기 위한 방법을 마련해야 한다. 또한 연결이 비정상적으로 끊어졌을 때에도 대처해야 하는데, 이는 구현의 복잡성을 증가시킨다.
연결 유지 비용 : 웹소켓을 통해 통신을 하기 위해서는 TCP Connection을 항상 유지해야 하는데, 트래픽이 많아질수록 서버의 CPU에 많은 부하가 생긴다.
HTML5 이전의 웹 브라우저에서는 지원하지 않는다.