/////
Search
Duplicate

WebSocket

웹 소켓 프로토콜인 RFC 6455는 단일 TCP 연결을 통해 클라이언트와 서버 사이에 전이중 방향 통신 채널을 설정하는 표준화된 방법을 제공한다.

웹 소켓 이전 상황

HTTP 통신은 기본적으로 비연결성 통신이므로 클라이언트에게 한 번 보내고 나면 연결이 끊겨 지속적으로 데이터를 주고 받을 수 없다.
기존에 채팅을 구현하려면 일반적인 Java Socket을 사용해야 했다. 소켓의 통신 과정을 일일이 구현해야 했다.
TCP 네트워킹을 통해 만튼 채팅 프로그램 (JAVA)

Polling

평범한 http request를 일정한 주기로 서버에 요청하여 이벤트 내용을 전달 받는 방식
가장 간단한 방법이지만 클라이언트가 계속해서 요청을 하기 때문에 클라이언트가 많아지면 서버의 부담이 급증하게 된다.
그리고 실시간 통신이라고 부르기는 하지만 실시간 정도의 빠른 응답을 기대하기는 어렵다.

Long Polling

Polling과 비슷한 기법이나 실시간으로 데이터를 처리할 수 있는 기법이다.
작동 방식
1.
서버로 일단 http request를 보내고 그 상태로 계속 기다리다가 서버에서 해당 클라이언트로 전달할 이벤트가 있다면 그 순간 response 메시지를 전달하며 연결이 종료된다.
2.
해당 작업이 완료된 후 이후에는 클라이언트에서 곧바로 다시 http request를 보내 서버의 다음 이벤트를 기다린다.
일반 Polling과 비교했을 때 Polling 보다는 서버의 부담이 줄어든다는 장점이 있지만 클라이언트에게 동시에 많은 양의 메시지가 올 경우 Polling과 별 차이가 없게 되며, 다수의 클라이언트에게 동시에 이벤트가 발생될 경우에는 곧바로 다수의 클라이언트가 서버로 접속을 시도하게 되면서 서버의 부담이 급증하게 된다.

Streaming

일반적인 TCP Connection과 비슷하며, 클라이언트와 서버간 연결 된 연결 통로로 데이터를 보내는 방식
작동 방식
1.
Streaming은 Long Polling과 마찬가지로 처음에는 클라이언트에서 서버로 http request를 보낸다.
2.
서버에서 클라이언트로 이벤트를 전달할 때, 해당 요청을 끊지 않고 필요한 메세지만 보내기를 반복
서버에서 메세지를 보내고 나서 다시 http request연결을 하지 않아도 되어 Long Polling에 비해 부담이 덜 하다.
연결 시간이 길어질 수록 연결 유효성 관리의 부담이 발생한다.

한계점

위 세 가지 방법 모두 Http를 통해 통신하기 때문에 요청과 응답 시 헤더가 불필요하게 크다.
Long Polling과 Streaming 방식의 경우 서버에서 클라이언트로 메세지를 보낼 수는 있지만 클라이언트에서 서버로 메세지를 보내는 것에는 조금 어렵다는 문제점이 있다.

해결책

그래서 이렇게 약간의 문제가 있는 기술들 말고 정식으로 클라이언트와 서버간에 어려움 없이 양방향으로 통신이 가능하게 하기 위해서 HTML5 표준의 일부로 Web Socket이 만들어지게 되었다.
임시 방편으로 Ajax를 사용한 비동기적 통신을 통해 주기적으로 한 페이지 안에서 Server한테 자신에게 보낼 정보가 있는지 요청하거나, 페이지가 이동될 때마다 자신에게 온 정보가 있는지에 대한 질문을 요청에 포함할 수 있었다.
WebSocket과 AJAX의 비교

WebSocket

웹 소켓은 클라이언트가 접속 요청을 하고 웹 서버가 응답한 후 연결을 끊는 것이 아닌 Connection을 그대로 유지하고 클라이언트의 요청 없이도 데이터를 전송할 수 있는 프로토콜이다.
기존 TCP Socket과 다른 점은 최초 접속이 일반 HTTP Request를 통해 HandShaking 과정을 통해 이뤄진다는 점이다.
TCP는 이진 데이터만 주고 받을 수 있으나, 웹 소켓은 텍스트 데이터도 주고 받을 수 있다.
HTTP Request를 그대로 사용하기 때문에 기존의 80, 443 포트로 접속을 하므로 추가 방화벽을 열지 않고도 양방향 통신이 가능하고, HTTP 규격인 CORS 적용이나 인증 등 과정을 동일하게 가져갈 수 있는 것이 장점이다.
웹 소켓은 서비스를 동적으로 만들어 주지만 Ajax, Streaming, Long Polling 기술이 더 효과적일 수 있다. 예를 들어 변경 사항의 빈도가 자주 일어나지 않고, 데이터의 크기가 작은 경우이다.
반대로 실시간성을 보장해야 하고, 변경 사항의 빈도가 잦다면, 또는 짧은 대기시간, 고주파수, 대용량의 조합인 경우 WebSocket이 좋은 해결책이 될 수 있다.

WebSocket 동작 과정

웹 소켓도 TCP/IP 위에서 동작하기 때문에 서버와 클라이언트는 웹 소켓을 사용하기 전에 서로 TCP/IP 접속이 되어 있어야 한다.
WebSocket 동작 과정은 크게 세 가지로 나눌 수 있다.
빨간색 : Opening HandShake
노란색 : Data Transfer
보라색 : Closing HandShake

Opening HandShake 단계

Opening HandShake와 Closing HandShake는 일반적인 HTTP TCP 통신의 과정 중 하나이다.
접속 요청은 HTTP로 한 뒤 WebSocket 프로토콜로 변경된다.

HandShake Request

HandShake Response

Data Transfer 단계

Opening HandShake에서 승인이 나고나면, 웹 소켓 프로토콜로 노란색 박스 부분인 Data transfer 이 진행된다.
여기서 데이터는 메시지라는 단위로 전달된다.
메시지 : 여러 프레임이 모여서 구성되는 하나의 논리적인 메시지 단위
프레임 : 통신에서 가장 작은 단위의 데이터.
참고로 가장 작은 단위의 데이터는 패킷이라고 부르지 않나? 라고 생각할 수도 있지만 패킷은 전 네트워크 통신 과정에서 가장 작은 단위의 데이터를 뜻하고 프레임은 데이터 링크 계층에서 주고 받는 가장 작은 단위를 의미한다.

순수 Web Socket을 사용했을 때 문제점

모든 클라이언트의 브라우저에서 WebSocket을 지원한다는 보장이 없다.
또한 Server/Client 중간에 위치한 Proxy가 Upgrade 헤더를 해석하지 못할 수도 있다.
Server/Client 중간에 위치한 Proxy가 유휴 상태에서 도중에 Connection을 종료시킬 수도 있다.

그럼 어떻게 해야할까 → 바로 WebSocket Emulation을 이용하는 것이다.

이것은 우선 WebSocket 연결을 시도하고 실패할 경우 HTTP Streaming, Long-Polling 같은 HTTP 기반의 다른 기술로 전환해 다시 연결을 시도하는 것을 말한다.
일반적으로 node.js를 사용한다면 Socket.io를 사용하고, Spring을 사용한다면 SockJS를 이용한다.