최근 이직을 위해 면접을 보러 다니는 중에 웹소켓에 관한 질문을 받은 적이 있다.
socket.io를 이용해서 실시간 채팅 서비스를 만들었고 그 과정에서 웹소켓에 관한 공부를 진행한적이 있는데,
막상 면접에서 조금 딥하게? 질문이 들어오니 제대로 답변하지 못한 기억이 있어 자세하게 정리해보려고 한다.
- socket.io 가 웹소켓 이랑 정확히 어떻게 다른지?
- 대용량 메세지가 들어오면 어떻게 처리할 것인지?
- 의도치않게 소켓 통신이 끊기면 어떻게 처리할 건지?
이런 질문들에 대해 정확하게 답변을 못했던 것 같다.
아무래도 개념적인 부분을 빠르게 훝고 구현에만 너무 초점만 맞춰서 개발했던 것 같다.
클라이언트와 서버간의 양방향 통신을 위해 소켓은 너무나도 중요한 개념이고 이번기회에 확실히 정리해보려고 한다.
우선, 개념과 이론적인 정리를 한 후에 간단하게 socket.io 사용하여 채팅 서비스를 만들어 보는 순서로 작성할 예정
✔️ 웹소켓 이란?
웹 소켓은 사용자의 브라우저와 서버 사이의 인터액티브 통신 세션을 설정할 수 있게 하는 고급 기술입니다. 개발자는 웹 소켓 API를 통해 서버로 메시지를 보내고 서버의 응답을 위해 서버를 폴링하지 않고도 이벤트 중심 응답을 받는 것이 가능합니다.
https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API
mdn에 나와있는 정의는 다음과 같다.
정리하자면, 일반적으로 클라이언트 - 서버 구조의 프로그램에서 서버에있는 리소스가 필요할 때
우리는 서버에게 필요한 데이터를 요청 (request) 해야합니다. 그러면 서버는 해당 요청에 맞는 응답(response)을 보내게 됩니다.
여기서 뭘 요청할지? 어떻게? 요청을 보내고 받을 것인가에 관한 일정한 약속이 필요합니다.
마치 음식을 주문할 때 주문서를 넣는 것 처럼요,
보통 이때 사용 되는 통신 규약을 우리는 프로토콜 이라고 하고 웹에서 사용 되는 전송 프로토콜을 http 라고 합니다.
✔️ http vs socket ?
즉, http 와 웹소켓은 클라이언트 - 서버 구조의 네트워크 상에서 통신을 하기 위한 통신규약, 방법을 말합니다.
차이점이 있다면 소켓 통신은 서버와 클라이언트 간의 양방향 통신을 위해 사용된다고 생각 하면 됩니다.
🧐 http 주요 특징
- Stateless (무상태성)
http 통신의 경우 상태를 가지고 있지 않습니다.
무슨 말이냐면, 클라이언트 - 서버 구조에서 각각 의 요청에 대한 정보를 저장 하지 않는 다는 말입니다.
이게 조금 추상적으로 들리는데 쉽게말해서 서버에서 응답 후 클라이언트의 리소스(로그인 여부, 데이터 리소스) 등등 을 전부 기억하고 있다면 확장성도 떨어지고 비용도 심할 것 입니다.
반대로 클라이언트에서도 서버에 디비 구조라던가.. 이런거에 의존하고 있지 않고 독립된 요청 - 응답 방식으로 동작합니다. - Connectionless(비연결성)
비연결성의 경우 말그대로 클라이언트 - 서버 간의 요청 - 응답 이 각각 독립적으로 이루어 진다는 것
요청 - 응답이 이루어 지면 이 연결상태를 유지하는게 아니라 끊어 버립니다.
연결 상태를 유지 하는 것도 전부 비용이 들기 때문에 불필요한 리소스를 줄이기 위해 이러한 특성을 갖습니다.
🧐 양방향, 실시간 연결은?
http의 이러한 특징과 한계점으로 인해 양방향으로 서버와 클라이언트의 실시간 연결이 필요한 경우 (실시간 채팅, 주식 등)
http 통신에서는 polling이라는 기법을 사용했습니다.
HTTP Polling
서버에 일정주기로 요청을 송신한다. 따라서 불필요한 request와 connection을 생성한다. 변경사항이 없어도 요청을 보내고 응답을 받아야한다.
Long Polling
서버에 요청을 보내고 이벤트가 생겨 응답 받을때까지 연결을 종료하지 않는다.
응답 받으면 끊고 다시 요청을 보낸다.결국 많은 양의 요청이 쏟아질 경우 polling과 같다.
위와 같이 polling 방식의 경우 커넥션 유지를 위해 불필요한 요청과 재연결이 발생 하게 됩니다.
이러한 오버헤드를 줄이기 위해 사용 되는 게 웹소켓 입니다.
🧐 웹소켓 쓰면 뭐가 좋은데?
- 매 요청 마다 재연결을 하는게 아니라 한 번의 요청으로 연결을 유지하고 데이터를 주고 받을 수 있습니다.
- reconnection을 통해 연결을 유지 하는게 아닌 지속적인 전이중 통신(Full Duplex) 통신 채널 제공
- reconnection을 위한 정기적인 http 요청이 없으므로 불필요한 오버헤드를 줄일 수 있음
- 즉, 서버 입장에서도 네트워크 부하가 적으니 많은 클라이언트들의 실시간 연결이 필요한 (채팅 같은거) 경우 소켓 통신을 사용하는게 성능이나 확장성 면에서 더 효율 적입니다.
✔️ 그래서 웹소켓 어떻게 동작하는지?
- 우선 http 프로토콜을 통해 연결 요청을 보냅니다.
- http 통신을 통한 연결 과정에서 websocket 프로토콜로 upgrade 하기위한 정보들을 헤더에 실어서 보냅니다.
- 웹 소켓 연결을 위한 핸드쉐이크 프로세스가 실행 되며, (웹소켓의 경우 http request를 통해 핸드쉐이킹이 이루어 진다)
- 클라이언트가 서버의 응답을 수신하면 http 연결이 종료되고 웹소켓 연결이 설정됩니다.
- 이후,웹소켓 프로토콜을 통해 양방향 메세지 통신이 가능
✔️ 그럼 socket.io 는 뭐야?
Socket.IO is a library that enables low-latency, bidirectional and event-based communication between a client and a server.
It is built on top of the WebSocket protocol and provides additional guarantees like fallback to HTTP long-polling or automatic reconnection.
즉, socket.io는 기본적으로 Node.js 기반의 웹소켓 양방향 통신을 가능하게 해주는 라이브러리 입니다.
js 말고도 다양한 언어로도 구현어 되어있으며,
최신브라우저의 경우 일반적으로 WebSocket을 잘 지원하지만 구형 브라우저나 특정 네트워크 환경에서 호환성 이슈가 있을 수 도 있다.
socket.io 의 경우 추가적으로 long-polling 방식의 fallback (폴백은 웹소켓 사용 못하면 롱폴링 방식으로 동작 한다는 소리임)
이나 자동 재연결 등에 추가적인 구현이 되어있는 라이브러리 입니다.
이외에도..
- Packet Buffering
- 클라이언트 연결이 끊긴 경우 패킷이 자동으로 버퍼되고, 다시 연결된 후에 전송된다.
- Broadcasting
- 연결된 모든 클라이언트에게 메세지 보내기 등이 가능하다.
- Multiplexing
- 사용자가 특정 그룹에 참여하게 만들어, 특정 그룹에게만 메세지 보내는 것이 가능하다.
이러한 추가 기능을 제공하며 내가 참여했던 프로젝트는 Multiplexing, Broadcasting 같은 기능(그룹 별 채팅방이 필요 했었음)이
서버에서 필요해서 socket.io를 선택했었다.
✔️ 세줄 요약
- 소켓? -> TCP / IP 레이어에서 이루어지는 양방향 통신을 위한 연결체
- 웹소켓? -> http 프로토콜로 연결 요청하는 양방향 통신 프로토콜 (물론 이것도 TCP / IP 기반)
- socket.io -> 웹소켓 기반의 양방향 통신 구현한 라이브러리 (웹소켓 말고도 long polling fallback 등 추가적인 기능 제공)
참고한 글
https://jake-seo-dev.tistory.com/251
https://velog.io/@kaitlin_k/websocket
조만간 socket.io 사용한 간단한 채팅 예제 구현해서 2탄 업로드 하겠습니다 ㅎ
'CS' 카테고리의 다른 글
토큰 기반의 로그인 인증 방법 이해하기 (JWT) (4) | 2022.04.30 |
---|---|
사용자 로그인 이해하기 (쿠키와 세션) (0) | 2022.04.25 |
SSR CSR 차이 (0) | 2022.04.08 |
jpg, png, svg 차이, 리액트에서 svg 다루기 (0) | 2022.01.25 |
댓글