Websocket, Socket.io

pds·2022년 12월 31일
1

TIL

목록 보기
29/60

stateful 양방향 통신이라는 것만 알고 있었지 한 번도 사용해보거나 공부해본 적은 없는 웹소켓이었다.

최종프로젝트 때 활용이 확정적이라 미리 간단하게 개념에 대해 공부해보기로 하였다.

Websocket

HTML5 표준 기술로 HTTP 환경에서 클라이언트와 서버 사이에 하나의 TCP 연결을 통해 실시간으로 양방향통신을 가능하게 하는 프로토콜

기존의 HTTP 프로토콜과는 달리 WebSocket은 클라이언트와 서버간 지속적인 연결을 유지하며

데이터 전송에서도 적은 오버헤드를 가지고 빠르고 효율적으로 통신할 수 있게 한다.

기존 Stateless한 REST 방식의 HTTP통신에서는 다수의 URI와 Http Method들을 통해 웹 어플리케이션과 상호작용하는 형태였다.

하지만 웹소켓은 초기에 연결을 한 번 수립하기 위한 하나의 URI만 존재하고 모든 메시지는 초기에 연결된 TCP로만 통신한다.


장점

실시간 통신이 가능하다.

짧은 시간에 빠르고 많은 요청과 응답이 오가는 형태라면 Stateless보다 훨씬 효율적이다.

채팅, 게임 등 실시간성 서비스에 매우 적합하다.


단점

연결을 유지하면서 데이터를 주고받기 때문에 계속해서 서버와 클라이언트 간 연결을 유지해야되서 불필요하게 서버의 자원을 소비하게 될 수도 있다.

실시간으로 통신이 필요한 경우가 아니라면 사용하지 않아야 할 것 같다.


Websocket Handshake 과정

(1) 소켓 인스턴스를 생성하면 즉시 서버와 연결이 시작된다.

(2) 클라이언트가 HTTP UPGRADE 요청으로 서버에 웹소켓을 지원하는지 확인한다.

nginx 예시

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

UPGRADE: 프로토콜을 전환하기 위해 사용하는 헤더로 웹소켓 요청 시에는 반드시 websocket이라는 값을 가짐

Connection: 현재의 전송이 완료된 후 네트워크 접속을 유지할 것인가에 대한 정보. 웹소켓 요청 시에는 반드시 Upgrade라는 값을 가짐

그 외의 키 값과 origin 등을 보낸다.


(3) 서버에서 동의되면 status 101로 응답해주고 Handshake 과정이 종료되며 이제 Websocket 프로토콜로 실시간으로 통신할 수 있게 된다.


Socket.io

WebSocket을 기반으로 한 Javascript 라이브러리로 웹소켓보다 다양한 기능과 브라우저 호환성을 제공하며 더욱 복잡한 실시간 웹 애플리케이션을 구현할 때 사용한다.

Socket.io는 WebSocket, FlashSocket, AJAX Long Polling, AJAX Multi part Streaming, IFrame, JSONP Polling을 하나의 API로 추상화한 것이다.

즉 브라우저와 웹 서버의 종류와 버전을 파악하여 가장 적합한 기술을 선택하여 사용하는 방식이다.

Websocket을 지원하지 않는 구형 브라우저와 모바일 기기에서도 사용가능하도록 다양한 전송 방식(Polling, Long Polling)을 지원한다.

Room, NameSpace 개념이 있어 격리된 클라이언트에게만의 브로드캐스팅이 가능하다.

소켓 연결 실패 시 fallback기능을 통해 다른 방식으로 알아서 해당 클라이언트와 연결을 시도한다.


연습하면서 해봤는데 위의 에러는 서버측에서 UPGRADE, Connection 헤더를 허용해두지 않아서 ws 프로토콜로 연결 수립이 되지 않아 발생한 것이다.

이 경우 아래처럼 알아서 polling 방식으로 통신을 시도한다.

근데 polling 방식이라는 것이 무엇일까?


서버의 Event를 클라이언트로 보내는 방법

Polling

클라이언트가 평범한 http request를 서버로 계속 날려서 이벤트 내용을 전달받는 방식이다.

가장 쉬운 방법이나 클라이언트가 계속 요청을 보내야해서 클라이언트가 많아지면 서버의 부담이 급증한다.

http 오버헤드가 발생하지만 일정하게 갱신되어야 하는 서버데이터를 보여줘야하는 경우 유용하게 사용할 수 있는 방식이다.


Long Polling

클라이언트가 서버에게 요청을 보내고 서버는 해당 요청에 대해 응답을 보내지 않고 일정 시간동안 대기한 후에 응답을 보내는 방식으로 실시간 통신을 구현하는 방법

클라이언트에서 서버로 http 요청을 보내도 응답하지 않다가 새로운 데이터가 도착하거나 일정 시간이 지난 후에 응답을 반환한다.

서버는 새로운 데이터가 도착할 때마다 응답을 반환하거나 일정 시간이 지나면 빈 응답을 반환한다.

일반 Polling보다는 부하가 적겠으나 클라이언트로 자동으로 보내는 이벤트 시간 간격이 좁다면 polling과 별 다를게 없다.

또한 다수의 클라이언트에게 동시에 이벤트를 보내야한다면 서버의 부담이 급증한다.

socket.io에서는 transport=polling일 경우 기본적으로 long-polling 방식을 사용한다.


WebSocket

기존 http요청 응답 방식은 요청한 그 클라이언트에만 응답이 가능했는데

ws 프로토콜을 통해 웹소켓 포트에 접속해 있는 모든 클라이언트에게 이벤트 방식으로 응답한다

최초 접속이 일반 http request를 통해 handshaking과정을 통해 이루어 지기 떄문에

기존의 80, 443 포트로 접속을 하므로 추가로 방화벽을 열지 않고도 양방향 통신이 가능하고

http 규격인 CORS적용이나 인증등의 과정을 기존과 동일하게 가저갈 수 있는것이 장점이다

profile
강해지고 싶은 주니어 프론트엔드 개발자

0개의 댓글