그리미
Socket.IO doc 을 통해 공부해보자 본문
Socket.IO란 무엇 입니까
Socket.IO는 클라이언트와 서버 간의 저지연 , 양방향 및 이벤트 기반 통신을 가능하게 하는 라이브러리
Socket.IO 연결은 다양한 저수준 전송을 통해 설정될 수 있습니다.
특징
HTTP 롱폴링 폴백
WebSocket 연결을 설정할 수 없는 경우 연결은 HTTP 롱폴링으로 전환됩니다.
자동 재연결
서버와 클라이언트 간의 WebSocket 연결이 중단될 수 있으며, 양측 모두 링크의 끊어진 상태를 알지 못할 수 있습니다.
이러한 이유로 Socket.IO에는 연결 상태를 주기적으로 확인하는 하트비트 메커니즘이 포함되어 있습니다.
그리고 결국 클라이언트의 연결이 끊어지면 서버에 과부하가 걸리지 않도록 지수적 백오프 지연을 거쳐 자동으로 다시 연결합니다.
패킷 버퍼링
클라이언트의 연결이 끊어지면 패킷이 자동으로 버퍼링되고, 다시 연결되면 전송됩니다.
멀티플렉싱
네임스페이스를 사용하면 단일 공유 연결을 통해 애플리케이션의 로직을 분할할 수 있습니다. 이는 예를 들어 권한이 있는 사용자만 참여할 수 있는 "관리자" 채널을 만들려는 경우에 유용할 수 있습니다.
일반적인 질문
오늘날에도 Socket.IO가 필요한가요 ?
웹소켓은 이제 거의 모든 곳에서 지원되므로 타당한 질문입니다 .
즉, 애플리케이션에 일반 웹 소켓을 사용한다면 결국에는 재연결 , 확인 , 브로드캐스팅 과 같이 Socket.IO에 이미 포함되어 있고 실제 테스트를 거친 대부분의 기능을 구현해야 할 것입니다 .
Socket.IO 프로토콜의 오버헤드는 무엇입니까 ?
socket.emit("hello", "world")다음을 포함하는 단일 WebSocket 프레임으로 전송됩니다 42["hello","world"].
- 4Engine.IO "메시지" 패킷 유형입니다.
- 2Socket.IO "메시지" 패킷 유형입니다.
- ["hello","world"]JSON.stringify()인수 배열의 -ed 버전 임
따라서 각 메시지마다 몇 바이트가 추가되는데, 사용자 정의 파서를 사용하면 이를 더욱 줄일 수 있습니다
Socket.IO 코드베이스는 두 개의 뚜렷한 계층으로 나뉩니다.
- 저수준 배관: 우리가 Engine.IO라고 부르는 Socket.IO 내부의 엔진
- 상위 수준 API: Socket.IO 자체
엔진.IO
Engine.IO는 서버와 클라이언트 간의 저수준 연결을 설정하는 역할을 합니다. 다음을 처리합니다.
- 다양한 운송 수단 과 업그레이드 메커니즘
- 단절 감지
업그레이드 메커니즘
기본적으로 클라이언트는 HTTP 롱폴링 전송을 통해 연결을 설정합니다.
하지만, 왜 그럴까?
WebSocket이 양방향 통신을 구축하는 가장 좋은 방법이기는 하지만 경험에 따르면 회사 프록시, 개인 방화벽, 바이러스 백신 소프트웨어 등으로 인해 WebSocket 연결을 구축하는 것이 항상 가능한 것은 아닙니다.
사용자 관점에서 실패한 WebSocket 연결은 실시간 애플리케이션이 데이터 교환을 시작할 때까지 최대 10초까지 기다릴 수 있습니다. 이는 사용자 경험을 지각적으로 손상시킵니다.
요약하자면 Engine.IO는 먼저 안정성과 사용자 경험에 중점을 두고, 그다음으로 잠재적인 UX 개선과 서버 성능 향상에 중점을 둡니다.
업그레이드하려면 클라이언트가 다음을 수행해야 합니다.
- 나가는 버퍼가 비어 있는지 확인하세요
- 현재 전송을 읽기 전용 모드로 전환
- 다른 운송 수단과 연결을 시도하세요
- 성공하면 첫 번째 전송을 닫습니다.
브라우저의 네트워크 모니터에서 확인할 수 있습니다.
- 핸드셰이크(세션 ID 포함 — 여기서는 zBjrh...AAAK후속 요청에서 사용됨)
- 데이터 전송(HTTP 롱폴링)
- 데이터 수신(HTTP 롱폴링)
- 업그레이드(WebSocket)
- 데이터 수신(HTTP 롱폴링, 4. WebSocket 연결이 성공적으로 설정되면 닫힘)
연결 해제 감지
Engine.IO 연결은 다음과 같은 경우 닫힌 것으로 간주됩니다.
- 하나의 HTTP 요청(GET 또는 POST)이 실패하는 경우(예: 서버가 종료된 경우)
- WebSocket 연결이 닫혔습니다(예: 사용자가 브라우저에서 탭을 닫을 때)
- socket.disconnect()서버 측 또는 클라이언트 측에서 호출됩니다.
서버와 클라이언트 간의 연결이 여전히 유지되고 있는지 확인하는 하트비트 메커니즘도 있습니다.
주어진 간격( pingInterval핸드셰이크에서 전송된 값)에서 서버는 PING 패킷을 보내고 클라이언트는 몇 초( pingTimeout값) 동안 PONG 패킷을 다시 보냅니다. 서버가 PONG 패킷을 다시 받지 못하면 연결이 끊어진 것으로 간주합니다. 반대로 클라이언트가 그 안에 PING 패킷을 받지 못하면 pingInterval + pingTimeout연결이 끊어진 것으로 간주합니다.