웹 소켓 프로토콜인 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를 이용한다.