Socket.IO 서버 (Node.js) 와 Socket.IO 클라이언트 (브라우저, Node.js, 혹은 다른 언어들) 간 양방향 채널은 가능 할 때 WebSocket 연결로 설정되며, HTTP long-polling 을 fallback 으로 사용한다.
Socket.IO 코드베이스는 두 개의 레이어로 나눠져 있다.
Engine.IO 는 서버와 클라이언트간의 로우 레벨 연결 설립을 책임지고 있다.
소스 코드는 여기서 찾을 수 있음:
현재 전송은 두 개가 구현되어 있다.
HTTP long-polling 전송은 ("폴링" 이라고도 함) 연속적인 HTTP 전송으로 이루어진다.
GET
요청은 서버로부터 데이터를 수신하기 위함POST
요청은 서버로 데이터를 전송하기 위함전송의 특성상, 연속적 emit은 연결 되어 동일한 HTTP 요청 내에서 전송될 수 있다(?).
WebSocket 전송은 서버와 클라이언트 사이에 양방향 및 저지연시간 통신 채널을 제공하는 WebSocket 연결로 구성된다.
전송의 특성상, 각 emit 은 각자 WebSocket 프레임으로 전송된다 (일부 emit 은 두 개의 WebSocket 프레임으로 나눠질 수도 있다. 더 많은 정보는 여기
Engine.IO 연결 시작 때 서버는 몇 개의 정보를 보낸다.
{
"sid": "FSDjX-WRwSA4zTZMALqx",
"upgrades": ["websocket"],
"pingInterval": 25000,
"pingTimeout": 20000
}
sid
는 세션의 ID 다. 모든 후속 HTTP 요청에는 반드시 sid
쿼리 파라미터가 포함되어야 한다.upgrade
배열은 서버에 의해 지원되는 "더 나은" 전송의 리스트를 담고 있다.pingInterval
과 pingTimeout
값은 심박수 메커니즘에 사용된다.기본 값으로, 클라이언트는 HTTP long-polling 전송으로 연결을 맺는다.
WebSocket 은 분명히 양방향 통신을 맺는 가장 좋은 방법이나, 경험에 따르면 조직의 프록시 설정, 개인 방화벽 백신 소프트웨등에 의해 WebSocket 연결을 맺는게 항상 가능한 일은 아니다.
사용자의 관점에서 성공적이지 못한 WebSocket 연결은 실시간 애플리케이션이 데이터 교환을 시작하기까지 최대 10초를 기다려야 변환된다. 사용자 경험을 저해하는 것이다.
요악하면 Engine.IO 는 신뢰성과 사용자 경험을 우선으로 하며, 두 번째로 잠재적인 사용자 경험 개선과 서버 성능 향상에 중점을 둔다.
업그레이드 하기위해 클라이언트는
브라우저의 네트워크 모니터에서 확인할 수 있다.
Engine.IO 연결이 닫힌 것으로 간주될 때
socket.disconnect()
가 호출 되었을 때서버와 클라이언트가 아직 살아있고 작동 중인지 확인하는 심박수 메커니즘도 있다.
주어진 인터벌 (핸드 셰이크시 보내진 pingInterval
값)에 서버가 PING 패킷을 전송하고, 클라이언트가 PONG 패킷을 돌려 보낼 몇 초의 시간이 있다 (pingTImeout
값) 서버가 PONG 패킷을 수신 받지 못하면 연결이 닫힌 것으로 간주한다. 반대로, 클라이언트가 PING 패킷을 pingInterval + pingTimeout
내에 수신하지 못해도 연결이 닫힌 것으로 간주한다.
연결이 끊기는 이유는 여기(서버 사이드) 와 여기 (클라이언트 사이드)
Socket.IO 는 Engine.IO 위에서 몇 가지 추가 기능을 제공한다.
소스코드는 여기서 찾을 수 있다.