티스토리 뷰

websocket

하나의 TCP 접속에 전이중 통신 채널을 제공하는 컴퓨터 프로토콜, HTTP와 구별된다.

간단히 말하면 서버와 클라이언트 간의 메세지 교환을 위한 통신 규약(프로토콜)

 

웹 소켓의 특징

양방향 통신(full-duplex)

데이터 송수신을 동시에 처리할 수 있는 방법 

통상적으로 HTTP 통신은 client 가 요청을 보내는 경우에만 Server가 응답을 하는 단방향 통신이지만, 웹 소켓은 양방향 통신이 가능하다.

 

실시간 네트워킹(Real Time Networking)

웹 환경에서 연속된 데이터를 빠르게 노출하는 것 e.g.) 채팅, 주식


소켓 이전의 통신 방식 

1. Polling(폴링)

웹 소켓이 나오기 전의 통신 방식으로는 폴링(polling)방식을 사용하였다. 

[개념] 일정한 주기로 서버에 요청을 보내는 방식 

  • setTimeout, setInterval 등으로 일정 주기마다 서버에 요청을 보낸다.
  • 불필요한 요청과 connection을 생성하여 서버에 부하를 준다.
  • HTTP 통신을 하기 때문에 Request, Response 헤더가 불필요하게 크다. 

1-1. 폴링 방식을 선택하는 경우

  • 응답을 실시간으로 받지 않아도 되는 경우
  • 다수의 사용자가 동시에 사용하는 경우
  • e.g.) 페이스북 웹 채팅, 구글 메신저, msn 웹 메신저

2. Long Polling(롱 폴링)

[개념] 요청을 보냈을 때, 서버가 응답을 바로 보내지 않고 특정 이벤트나 타임아웃이 발생했을 때 응답을 전달하는 방식

폴링과 비슷하게 일정 주기로 요청을 보내지만 서버가 응답을 바로 전달하지 않는 특징을 가진다. 

불필요한 요청을 보내지않아 폴링방식보다는 좋아보이지만, 동시 다발적인 응답이 생기면 부하가 발생할 수 있다.

 

2-1. 롱 폴링 방식을 선택하는 경우

  • 응답을 실시간으로 받아야하는 경우
  • 적은 수의 사용자가 동시에 사용하는 경우

긴단 요약: 주기적으로 요청을 보내는 방식: 폴링, 롱폴링(서버에 너무 짧은 주기로 물어보면 부하문제때문에 일정 간격을 두고 요청을 다시 보내는 방식, 데이터가 있다면 데이터를 받고나서 다시 보내는 방식)

3. Streaming(스트리밍, HTTP Streaming)

[개념] 이벤트가 발생했을 때 응답을 내려주되, 응답을 완료시키지 않고 계속 연결을 유지하는 방식

롱 폴링에 비해 응답마다 다시 요청을 하지 않아도 된다. => 좀 더 효율적

하지만, 연결 시간이 길어질수록 연결 유효성 관리의 부담이 발생한다. 

 

결론: 소켓 이전의 1,2,3 방법 모두 HTTP 통신을 하기 때문에 Request, Response 헤더가 불필요하게 크며 서버 부하를 발생시킨다. 

리액트와 node.js로 구성된 백엔드에서 소켓 통신하기 

🤸‍♀️Socket.IO

[개념] 클라이언트와 서버 간의 짧은 대기 시간, 양방향 및 이벤트 기반 통신을 가능하게 하는 라이브러리

  • WebSocket 프로토콜 위에 구축되어 있으며 HTTP 간 롱폴링 또는 자동 재연결에 대한 폴백과 같은 추가 보장을 제공한다. 
  • 주의) Socket.IO는 WebSocket 구현이 아니다. (둘은 다른 것) => WebSocket 클라이언트가 Socket.IO서버에 성공적으로 연결할 수 없고 Socket.IO 클라이언트가 일반 WebSocket 서버에 연결할 수 없는 이유
  • Socket.IO 라이브러리는 서버에 대한 열린 TCP 연결을 유지하므로 사용자의 배터리가 많이 소모될 수 있다. (Socket.IO는 모바일 어플리케이션의 백그라운드 서비스에 사용하기 위한 것 x) 

Socket.IO 가 일반 WebSocket을 통해 제공하는 기능 

  • HTTP 롱폴링 - WebSocket 연결을 설정할 수 없는 경우 연결은 HTTP 롱 폴링으로 대체된다. (연결 실패시 롱폴링을 시도)
  • 자동 재연결 - heartbeat 매커니즘을 통해 연결상태를 체킹한다. 
  • 패킷 버퍼링 - 클라이언트가 연결이 끊겼을 때 패킷은 자동적으로 버퍼링되고 다시 연결되면 전송된다.

socket.io 사용하기

  • socket.io는 사실상 리액트와 그렇게 잘 어울리지 않는다. => 한 번, 연결해놓으면 `전역적인` 특성을 띄기 때문에 하나의 컴포넌트에 연결을 하고 다른 컴포넌트로 넘어갔을 때(이전 컴포넌트가 언마운트되어 화면에서 사라졌을 때), 연결이 끊어질 수 있다. (하나의 컴포넌트에 종속되게 만들면 안좋다.)
  • 그렇기 때문에 공통된 컴포넌트에 socket.io를 넣어준다. (이전에는 HOC를 사용했으나 hook으로 대체가능)
  • hook으로 대체가능한 경우는, 화면단(화면에 표시되는 ui적 요소)가 없고 로직만 들어가있을 때 사용하면 좋다. ( 화면단이 들어가 있어도 hooks로 빼는데 제약이 있는 것은 아님)
  • e.g) useSocket.ts 이런 식으로 커스텀 훅으로 분리
댓글