Socket.io 특징과 작동원리 살펴보기
저번 글에선 WebSocket의 개념에 대해 알아봤는데요. 이번 글에선 Socket.io에 대해 알아보겠습니다. Socket.io는 실시간 양방향 이벤트 기반의 통신을 지원하는 라이브러리입니다. Socket.io는 저지연으로 다양한 기능을 파워풀하게 지원합니다.
Socket.io의 특징
Socket.io는 여러가지 통신 방식으로 실시간 통신이 가능합니다.
- HTTP long-polling
- WebSocket
- WebTransport
기본적으로 WebSocket이 사용되며 HTTP long-polling이 fallback으로 사용됩니다. 기본적으로 node.js와 함께 사용되지만 Java, C++, Python 등의 언 어와 사용도 가능합니다.
Socket.io가 지원하지 않는 것
WebSocket과 기능적으로는 유사하지만 Web socket의 구현체가 아니라서 일반 WebSocket 서버에 접속할 수 없습니다.(ws://)
서버에 대한 TCP 연결을 유지하므로 사용자의 배터리가 많이 소모될 수 있습니다.
동작원리
Socket.io는 두개의 별개 레이어로 구성됩니다.
- Engine.io라고 불리는 Socket.io의 엔진
- Socket.io
Engine.io
서버와 클라이언트의 저수준 연결을 설정하는 역할을 합니다. 다양한 통신 수단과 업그레이드 메커니즘, 통신 중단 감지를 처리합니다.
Handshake
Engine.io의 연결이 시작되면 서버는 아래와 같은 정보를 전송합니다.
{
"sid": "FSDjX-WRwSA4zTZMALqx",
"upgrades": ["websocket"],
"pingInterval": 25000,
"pingTimeout": 20000
}
sid
: Session의 id입니다. 이후의 모든 HTTP request query parameter에 포함되어야 합니다.upgrades
: 최선의 통신방법들이 배열로 제공됩니다.pingInterval
,pingTimeout
: heartbeat 메커니즘에 사용되는 값 입니다.
Upgrade mechanism
기본적으로 클라이언트는 HTTP long-polling으로 연결을 설정합니다. 왜냐면 웹소켓은 실시간 양방향 통신을 이용하는데 가장 좋은 방법이지만 각종 방화벽, 보안프로그램 등 때문에 항상 연결이 가능한 것은 아닙니다. 웹소켓을 처음부터 연결시도하면 데이터를 주고받을 때까지 사용자는 10초까지도 기다리게 될 수 있습니다. 사용자 경험을 해칠 수 있습니다.
그래서 socket.io는 다음과 같이 동작합니다.
- handshake
- 첫번째 데이터 전송(HTTP Long-polling)
- 첫번째 데이터 수신(HTTP Long-polling)
- (성공시) Upgrade(WebSocket)
- (웹소켓이 정상 동작하지 않을 경우를 대비해서) 두번째 데이터 수신(HTTP Long-polling)
- WebSocket이 정상적으로 연결되면 HTTP Long-polling이 닫힘
연결 해제 감지
Engine.io 연결은 다음의 경우에 닫혔다고 간주합니다.
- HTTP 요청이 실패하는 경우
- WebSocket 연결이 끊긴경우
- socket.disconnect() 한 경우
Heartbeat 메커니즘은 클라이언트와 서버간의 연결상태를 주기적으로 확인해서 연결이 여전히 유효한지 확인합니다. 네트워크 상태가 불안정하거나 연결이 끊긴 경우에 즉시 재연결을 하기 위함입니다.
Heartbeat 메커니즘은 다음과 같이 작동합니 다.
- Ping/Pong 메시지 전송: Socket.io는 주기적으로 서버에서 ping 메시지를 전송하고 client에서 pong으로 응답합니다.
- 주기 설정: handshake에서 제공된 pingInterval과 pingTimeout이 여기서 사용됩니다.
- pingInterval: 서버가 ping 메시지를 보내는 주기입니다.
- pingTimeout: 서버가 client의 pong 응답을 기다리는 시간입니다. 이 시간 내에 응답이 없으면 연결이 끊어진 걸로 간주합니다.
- 연결 유효성 확인: 클라이언트가 일정시간 내에 pong으로 응답하지 않으면 서버는 연결이 끊어진 것으로 간주하고 재연결을 시도합니다.
정리
Socket.IO는 실시간 양방향 통신을 지원하는 라이브러리로, Engine.IO를 통해 다양한 통신 방식을 선택하며 안정성을 확보합니다. 기본적으로 WebSocket을 사용하되, 문제가 생길 경우 HTTP long-polling으로 대체합니다. 연결 유효성을 위해 heartbeat 메커니즘을 통해 주기적으로 연결 상태를 확인하고, 필요 시 재연결을 시도합니다.
다음 글에서는 Socket.io를 이용해 간단한 채팅 어플리케이션을 개발하면서 기능에 대해 알아보겠습니다.
Appendix
https://socket.io/docs/v4/how-it-works/