클라이언트가 서버에 새로운 데이터나 이벤트가 있는지 주기적으로 요청을 보내 확인하는 통신 패턴
서버는 요청이 올 때마다 현재 시점의 정보를 응답하며, 클라이언트가 다음 요청을 보낼 때까지 기다리게 됨
특징
일반적으로 HTTP/1.1 이상은 지속 연결을 기본으로 사용하여, 클라이언트와 서버가 한 번 맺은 TCP 연결을 요청-응답 후에도 일정 시간 유지합니다.
따라서, 클라이언트가 다음 폴링 요청을 보낼 때 기존 연결을 재사용하게 되므로, 매번 3-way Handshake를 반복할 필요가 없어 폴링으로 인한 연결 설정 오버헤드가 크게 줄어듭니다.
클라이언트가 서버에게 데이터를 요청할 때, 서버에 새로운 데이터나 이벤트가 생길 때까지 연결을 끊지 않고 대기하도록 하는 통신 패턴
일반적인 Polling 방식의 비효율성을 개선하기 위해 고안되었음
동작 원리
클라이언트가 서버에 데이터를 요청하면, 서버는 즉시 응답하지 않고 요청을 붙잡아 두며, 서버에 새로운 데이터나 이벤트가 발생하면, 서버는 대기 중이던 요청에 대한 응답으로 해당 데이터를 클라이언트에 보내고 클라이언트는 응답을 받자마자 연결을 해제하고, 곧바로 새로운 Long-Polling 요청을 다시 보내 다음 이벤트를 기다립니다.
Polling은 클라이언트가 서버에 데이터를 주기적으로 요청하고 서버는 즉시 응답하는 방식이기에 새로운 데이터 유무와 관계없이 빈 응답이 대부분이라 네트워크 낭비가 심하고 다음 요청 주기가 될 때까지 지연이 발생할 수 있습니다.
반면, Long-Polling은 클라이언트 요청 시 서버가 새로운 이벤트가 발생할 때까지 연결을 장시간 유지한 후 데이터를 응답하기 때문에 불필요한 빈 응답이 없어 네트워크 낭비가 적으며, 이벤트 발생 시 데이터를 거의 즉시 수신할 수 있어 즉시성이 높습니다
특징
웹 브라우저와 서버 간에 지속적인 양방향 통신 채널을 제공하는 통신 프로토콜
특징
왜 WebSocket은 프로토콜 전환을 할까
웹의 기본 통신 규약인 HTTP의 한계를 벗어나 지속적인 양방향 통신 채널을 확보하기 위함
HTTP는 무상태 단발성 요청 응답 모델이기 때문에 서버가 클라이언트에게 데이터를 먼저 푸시하거나 지속적인 양방향 통신을 할 수 없습니다.
따라서, WebSocket은 이 HTTP의 제약을 벗어나 클라이언트와 서버의 양방향 통로를 통해 자유롭게 데이터를 주고받기 위해 HTTP와는 근본적으로 다른 통신 규약으로 전환합니다.
서버가 클라이언트에게 단방향으로 데이터를 실시간 스트리밍하는 통신 기술
클라이언트가 서버에 연결을 요청하면, 서버는 그 연결을 계속 유지하면서 새로운 이벤트가 발생할 때마다 클라이언트에게 데이터를 연속적으로 전송합니다.
동작 방식
Long-Polling과 비슷하게 연결을 유지하지만, 이벤트 발생 시 연결을 끊지 않고 데이터를 계속 보낸다는 점에서 차이가 있음
클라이언트가 서버에 일반 HTTP 요청을 보내는 것으로 시작되며 서버는 응답 시 브라우저에 이벤트 스트림이 시작됨을 알리고 연결을 지속적으로 유지합니다.
이후 서버는 새로운 이벤트가 발생할 때마다 유지 중인 동일한 연결을 통해 클라이언트에게 실시간으로 푸시합니다.
Polling, Long-Polling을 사용하지 않은 이유
주기적으로 요청을 반복하거나 연결을 끊었다가 다시 맺는 방식이기 때문에 네트워크 및 서버 자원 소모가 크고 지연이 발생하기 때문
websocket을 사용하지 않은 이유
대기열 시스템은 서버에서 클라이언트로의 단방향 통신만 필요하기 때문에, HTTP에서 WS 프로토콜 업그레이드와 더 많은 리소스를 사용해가며 양방향 채널을 유지하는 WebSocket을 사용할 이유가 없다고 생각했습니다.
특히 대기열 특성상 서버 부하나 네트워크 단절로 연결이 끊어졌다가 재접속해야 하는 상황이 빈번할 수 있는데, WebSocket은 재연결 로직을 직접 구현해야 하는 반면 SSE는 기본적으로 자동 재연결을 지원하기 때문에 시스템 안정성과 구현 편의성 측면에서 더 적합하다고 생각했습니다.
SSE의 재연결 방식 : SSE 연결을 할 때는
EventSource객체를 사용하는데 이 객체는 연결 상태를 모니터링하고 문제가 발생하면 자동으로 재연결을 시도합니다. (EventSourceAPI가 기본으로 제공하는 기능 )
왜 websocket의 양방향 연결은 SSE보다 더 많은 리소스를 쓰는가
SSE도 TCP 연결을 유지하는 건 맞지만, 단순히 HTTP 응답 스트림을 열어둔 상태에서 서버에서 클라이언트 단방향 데이터만 흘려보내는 구조라 관리 오버헤드가 적지만, WebSocket은 프로토콜 업그레이드, 양방향 통신 유지, ping/pong heartbeat 등 추가적인 상태 관리가 필요해 연결당 리소스 소모가 상대적으로 더 큽니다.
또한, WebSocket 메시지는 반드시 WebSocket 프레임 구조를 따라야 하기 때문에 부가 데이터가 존재하여 처리 오버헤드가 더 크지만, SSE는 단순한 텍스트 데이터이므로 별도의 처리가 필요 없어 오버헤드가 더 적습니다.
추가적으로 SSE는 서버에서 클라이언트로의 단방향 데이터 푸시에 최적화되어 있어, 서버는 연결마다 복잡한 상태를 유지하거나 추적할 필요 없이 클라이언트가 보낸 요청 정보를 기반으로 이벤트를 일방적으로 흘려보내므로 상태를 관리할 필요가 없지만, WebSocket은 다수의 클라이언트가 양방향을 맺기에 서버가 연결마다 세션 객체를 생성하여 관리해야 합니다.
ping/pong heartbeat : 클라이언트와 서버 간에 데이터 통신이 없는 비활성 상태일 때도, 연결이 여전히 살아있음을 확인하고 유지하기 위해 주기적으로 주고받는 제어 메세지