WebSocket

SW고구마·2021년 12월 5일
0

WebSocket

  • 기존의 단방향 프로토콜인 HTTP과 호환해 양방향 통신을 제공하기 위해 만들어진 프로토콜
  • 일반 Socket 통신과 달리 HTTP 80 Port를 사용해 방화벽에 제약이 없다.
  • 접속을 위해 HTTP 를 이용해 HandShake를 거친 후, 연결 이후에는 자체적인 WebSocket 프로토콜(ws)을 이용

등장배경


초기 웹의 탄생 목적은 문서 전달이었다. 따라서 HTTP 프로토콜은 이런 목적에 적합한 형태였다.
하지만 시간이 지남에 따라 기술이 발전되고 동적인 문서를 요청하기 시작했고 서버와 실시간으로 데이터를 주고 받기 위한 기술이 필요했다. 이를 위해 기존의 HTTP 통신을 활용한 Polling, long Polling, streaming과 같은 방식이 등장했지만 단방향 통신이라는 HTTP의 근본적인 한계를 극복할 수 없었다.
이를 위해 HTML5에서 양방향 통신이 가능한 WebSocket이 등장했다.

Polling, Long Polling, Streaming

Polling

Polling이란 쉽게 말하면 서버를 주기적으로 감시하는 것이라고 볼 수 있다.
클라이언트는 서버에 주기적으로 요청(request)을 보내면서 서버로부터 응답(response)을 받아 내용을 전달 받는 가장 쉬운 방식이다.

Polling의 특징

  • 서버로 지속적으로 요청을 보내기 때문에 클라이언트가 많은 경우 서버의 부담이 급증한다.
  • HTTP 커넥션을 맺고, 끊는 것을 반복하기 때문에 오버헤드 발생
  • 요청을 보내고 응답을 받는 형식이기 때문에 완전한 실시간 응답을 기대하기 어렵다.

Long Polling

Long Polling이란 지속적으로 요청(request)를 보내는 Polling 방식을 개선해낸 방식이다.
클라이언트에서는 요청을 보내고 요청의 타임아웃 시간동안 응답을 기다린다. 만약 서버에서 응답 보낼 이벤트가 없다면 보냈던 요청이 타임아웃되고, 이벤트가 있다면 클라이언트로 요청에 대한 응답을 반환한다.
클라이언트는 요청이 타임아웃되거나, 응답을 받은 경우 서버에 다시 요청을 보낸다.

Long Polling 의 특징

  • 지속적으로 요청을 보내는 Polling에 비해 요청을 보내고 기다리기 때문에 Polling 방식에 비해 서버의 부담이 적다
  • 서버에서 클라이언트로 보내는 이벤트의 시간간격이 좁다면 Polling 방식과 차이가 없음
  • 클라이언트의 수가 많아 보내야 할 이벤트가 동시에 발생하는 경우 서버의 부담이 증가

Streaming

Polling과 Long Polling 방식과 마찬가지로 클라이언트에서 서버로 요청(request)를 보낸다. 이후, 서버에서 클라이언트로 이벤트를 전달할 때 연결을 해제하지 않고 필요한 메시지만을 반복해서 보내는 방식이다.
Polling의 방식들과는 다르게 서버에 다시 요청을 보내 연결을 맺지 않아 커넥션을 만드는 오버헤드가 줄어 부담이 줄어든다.

이처럼 HTTP 통신은 커넥션의 연결/해제가 반복되어 효율이 많이 떨어지게 된다.
따라서 협업, 금융, 게임 등 실시간성이 보장되어야하는 환경에서는 웹소켓이 좋은 해결책이지만, 뉴스나 메일같이 변경사항의 빈도가 자주 발생하지 않는 경우는 위와 같은 방식이 더 효율적일 수도 있다.

WebSocket 동작 방식

웹소켓은 TCP/IP 위에서 동작하기 때문에 최초 접속에서만 일반적인 HTTP 프로토콜로 HandShaking을 수행
이후 HandShaking을 거쳐 소켓을 열고 난 후에는 http 기반의 websocket프로토콜(ws)로 운영된다.

Handshake를 위한 request,reponse 구조

request

Header NamedivDescription
GETRequire요청 명령어는 Get을 사용해야하고, HTTP 버전은 1.1 이상
HostRequire웹소켓 서버의 주소
UpgradeRequireWebSocket 이라는 단어를 사용해야 함(대소문자 구분 X)
ConnectionRequireUpgrade 라는 단어를 사용해야 함(대소문자 구분 X)
Sec-WebSocket-KeyRequire길이가 16Bytes인 임의로 선택한 숫자를 base64로 인코딩한 값
OriginRequire클라이언트의 주소로 클라이언트로 웹 브라우저를 사용하는 경우 필수항목이다
Sec-WebSocket-VersionRequire13을 사용한다.
Sec-WebSocket-ProtocolOption클라이언트가 사용하고 싶은 하위 프로토콜 이름을 명시
Sec-WebSocket-ExtensionsOption클라이언트가 사용하고 싶은 추가 옵션을 기술

response

Header NamedivDescription
HTTPRequire클라이언트의 요청에 이상이 없는 경우 101을 상태코드로 반환, HTTP 버전은 1.1 이상
UpgradeRequireWebsocket 이라는 단어를 사용해야 함(대소문자 구분 X)
ConnectionRequireUpgrade 라는 단어를 사용해야 함(대소문자 구분 X)
Sec-WebSocket-AcceptRequire클라이언트로부터 받은 Sec-WebSocket-Key를 사용하여 계산된 값
Sec-WebSocket-ProtocolOption서버가 사용하는 추가 옵션을 기술한다. 클라이 요청하지 않는 추가 옵션을 명시하면 HandShake는 실패
Sec-WebSocket-ExtensionsOption서버가 사용하는 추가 옵션을 기술한다. 클라이언트가 요청하지 않는 추가 옵션을 명시하면 HandShake는 실패

참고

개발하는 고라니 님의 블로그

profile
하루하루 조금씩이라도

0개의 댓글