하나의 TCP 커넥션으로 full duplex 통신을 제공하는 프로토콜이다.
즉, 서버와 클라이언트 사이에 🌟소켓 커넥션을 유지하면서 양방향 통신이 가능한 기술이라고 할 수 있다.
📚 full duplex?
- 두 대의 단말기가 데이터를 송수신하기 위해 동시에 각각 독립된 회선을 사용하는 통신 방식
- 송신선과 수신선선이 각각 존재하므로 데이터 송신과 동시에 수신이 가능
웹 소켓은 HTTP로 handshake를 하며 초기 통신을 시작한 후, 웹 소켓 프로토콜로 변환하여 데이터를 전송한다.
REST한 방식의 HTTP 통신에서는 많은 URI를 통해 application이 설계되는 반면 웹소켓은 초기에 연결한 오직 하나의 URL 만 존재하며, 모든 애플리케이션 메시지는 같은 TCP 커넥션을 통해 통신된다.
📚 handshake 요청
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade // HTTP 사용 방식을 변경
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: v10.stomp, v11.stomp, my-team-custom
Sec-WebSocket-Version: 13
📚 handshake 응답
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Client의 요청(Request)이 있을 때만 서버가 응답(Response)하여 해당 정보를 전송하고 곧바로 연결을 종료하는 방식
HTTP 통신은 Client-Server간 접속을 유지하지 않으며, Client-Server간 한 번에 한 방향으로만 통신이 가능한 half-duplex
통신이다.
따라서 주고받는 데이터의 양이 많아지게 된다면, 연결을 기다리는 시간이 포함되어 성능 저하가 발생하게 된다. 또한, HTTP는 지나치게 많은 헤더 데이터(800byte ~ 수 kbyte)를 가지고 있다.
또한 HTTP 통신은 요청-응답이 완료되면 Connection을 닫기 때문에 이론상 하나의 Server가 Port 수의 한계(n<65535)를 넘는 client의 요청을 처리할 수 있다.
✏️이러한 HTTP 통신은 실시간 연결이 아닌, 필요한 경우에만 서버로 접근하는 콘텐츠 위주의 데이터를 사용할 때 용이하다. 게시물에 대한 내용 요청을 위해 실시간 통신을 하게 된다면 게시물을 받은 후에도 연결이 성립되어 있어 부하가 걸리기 때문이다.
Server와 Client가 특정 Port를 통해 실시간으로 양방향 통신을 하는 방식
HTML5 부터 새로 도입된 웹 소켓은 웹 서버와 웹 브라우저가 지속적으로 연결된 TCP 라인을 통해 실시간으로 데이터를 주고 받을 수 있도록 한다. HTTP와 다르게 WebSocket은 수 byte 수준으로 압축이 가능하다는 장점도 존재한다.
또한 WebSocket은 Connection을 유지하고 있으므로, 가용 Port 수만큼의 Client와 통신할 수 있다.
✏️이러한 소켓 통신은 짧은 대기시간과 높은 볼륨이 필요한 경우에 효과적이다. 실시간 양방향 데이터 통신이 필요한 경우, 많은 수의 동시 접속자를 수용해야 하는 경우, 브라우저에서 TCP 기반의 통신으로 확장해야 하는 경우 등의 상황에서 사용하면 좋다.
HTTP는 클라이언트의 request + 서버의 response로 이루어져 있기 때문에, 서버에서 클라이언트로 요청이 불가능하였다.
따라서 웹 소켓이 생기기전 서버는 클라이언트에게 어떠한 정보를 알리기 위해 무식한 방법인 Polling, Long Polling을 통해 양방향 통신 기법을 사용하였다.
📚 Polling
일정한 주기를 가지고 계속 검사하는 기법
클라이언트에서 갱신 된 변경사항이 있는지 주기적으로 요청하여 확인하는, 즉 평범한 http request를 서버로 계속 날려서 이벤트 내용을 전달받는 방식이다. 대다수의 AJAX 응용 프로그램에서 사용되는 전통적인 기술이라고도 할 수 있다.
가장 쉬운 방법이지만, 클라이언트가 계속적으로 request를 날리기때문에 클라이언가 많아지면 서버의 부담이 급증하게 되어 HTTP 오버헤드가 일어날 가능성이 크다.( http request connection 자체가 부담이 증가) 또한, 실시간정도의 빠른 응답을 기대하기도 어렵다.
polling은 일정하게 갱신되는 서버 데이터의 경우 유용하게 사용할 수 있다. (ex. 대시보드 갱신)
📚 HTTP overhead
정보의 신뢰성 판단을 위한, 보내지는 헤더 같은 정보 때문에 오히려 데이터량이나 처리시간이 증가하는것
기존의 주기적인 Polling 방식 대신, 요청에 대한 응답을 서버 이벤트 발생 시점에 응답하는 방식이다.
서버 측에서 접속을 열어두는 시간을 길게하는 방식으로, 과정은 아래와 같다.
1) 클라이언트에서 서버로 http request를 날린다.
2) 서버에 응답에 대한 사용 가능한 데이터가 없으면 계속 기다리다가(요청을 보류) 서버에서 해당 클라이언트로 전달할 이벤트가 있다면 그순간 response 메시지를 전달하면서 연결이 종료된다.
3) 클라이언트에서는 곧바로 다시 http request를 날려서 서버의 다음 이벤트를 기다리게 되는 방식이다.
polling 방식보다는 서버의 부담이 줄겠지만 클라이언트로 보내는 이벤트들의 시간간격이 좁다면 별 차이가 없게 되며, 다수의 클라이언트에게 동시에 이벤트가 발생될 경우에는 곧바로 다수의 클라이언트가 서버로 접속을 시도하면서 서버의 부담이 급증하게 되는 단점이 있다.
HTML5 표준안이며 어느정도 웹소켓의 역할을 하면서 더 가볍다.
websocket 과 같이 양방향이 아닌 server
-> client
단방향이기에 서버의 event 나 message를 client 로 push 하는 작업에 유용하게 사용될 수 있다.
또한, 양방향이 아니기에 요청 시 ajax로 쉽게 이용할 수 있으며 재접속 처리 같은 대부분의 저수준 처리가 자동으로 지원된다.