티스토리 뷰
- Socket.IO 란
- Socket.IO 작동방식
Socket.IO 란
Socket.IO는 클라이언트와 서버 간의 짧은 대기 시간, 양방향 및 이벤트 기반 통신을 가능하게 하는 라이브러리이다.
WebSocket 프로토콜 위에 구축되었으며 HTTP Long Polling 또는 자동 재연결로의 Fallback과 같은 추가 보장을 제공한다.
Socket.IO는 실제로 가능한 경우 전송을 위해 WebSocket을 사용하지만 각 패킷에 추가 메타데이터를 추가한다.
이것이 WebSocket 클라이언트가 Socket.IO 서버에 성공적으로 연결할 수 없고 Socket.IO 클라이언트도 일반 WebSocket 서버에 연결할 수 없는 이유이다.
Socket.IO 작동방식
Socket.IO Server(Node.js)와 Socket.IO Client(Browser, Node.js or another programming language) 간의 양방향 채널은
가능할 때마다 WebSocket 연결로 설정되며 HTTP Long Polling을 Fallback으로 사용한다.
Socket.IO 코드베이스는 두 개의 개별 레이어로 나뉜다.
- the low-level plumbing: what we call Engine.IO, the engine inside Socket.IO
- the high-level API: Socket.IO itself
Engine.IO
Engine.IO는 서버와 클라이언트 간의 저수준 연결 설정을 담당한다.
- the various transports and the upgrade mechnism(다양한 전송 및 업그레이드 메커니즘)
- the disconnection detection(단선 감지)
Transports
HTTP long-polling
연속적인 HTTP 요청으로 구성된다.
- 서버에서 데이터를 수신하기 위한 장기 실행 GET 요청
- 서버에 데이터를 보내기 위한 단기 실행 POST 요청
WebSocket
서버와 클라이언트 사이에 양방향 및 저지연 통신 채널을 제공하는 WebSocket 연결로 구성된다.
전송의 특성으로 인해 각 방출은 자체 WebSocket Frame으로 전송된다.(일부 방출은 두 개의 별개의 WebSocket Frame을 생성할 수도 있다.)
Handshake
Enging.IO 연결이 시작될 때 서버는 몇 가지 정보를 보낸다.
{
"sid": "FSDjX-WRwSA4zTZMALqx",
"upgrades": ["websocket"],
"pingInterval": 25000,
"pingTimeout": 20000
}
- the sid is the ID of the session, it must be included in the sid query parameter in all subsequent HTTP requests
- the upgrades array contains the list of all "better" transports that are supported by the server
- the pingInterval and pingTimeout values are used in the heartbeat mechanism
Upgrade mechanism
기본적으로 클라이언트는 HTTP long-polling 전송과의 연결을 설정한다.
WebSocket은 분명히 양방향 통신을 설정하는 가장 좋은 방법이지만 경험에 따르면 회사 프록시, 개인 방화벽, 바이러스 백신 소프트웨어로 인해 WebSocket 연결을 설정하는 것이 항상 가능한 것은 아니다.
- Handshake
- Send data (HTTP long-polling)
- Receive data (HTTP long-polling)
- Upgrade (WebSocket)
- Receive data (HTTP long-polling, closed once the WebSocket connection in 4. is successfully established)
Disconnection detection
Engine.IO 연결은 다음과 같은 경우 닫힌 것으로 간주된다.
- 하나의 HTTP 요청 (GET 또는 POST) 이 실패할때 (예: 서버가 종료된 경우)
- WebSocket 연결이 닫힐때 (예: 사용자가 브라우저에서 탭을 닫을 때)
- socket.disconnect()가 서버 측 또는 클라이언트 측에서 호출 될때
서버와 클라이언트 간의 연결이 여전히 작동하고 실행중인지 확인하는 Heartbeat mechanism도 있다.
주어진 간격 (Handshake에서 전송된 pingInterval 값)에서 서버는 PING Packet을 보내고
클라이언트는 PONG Packet을 다시 보낼 수 있는 몇 초 (pingTimeout)가 있다.
서버가 Pong Packet을 수신하지 않으면 연결이 닫힌것으로 간주한다.
반대로 클라이언트가 pingInterval + pingTimeout 내에 PING 패킷을 수신하지 않으면 연결이 닫힌 것으로 간주한다.
Introduction | Socket.IO
What Socket.IO is
socket.io