정의
클라이언트가 서버로부터 실시간으로 데이터를 수신할 수 있도록 하는 W3C 표준 기술
왜 이 기술이 나왔을까?
먼저 실시간 통신을 가능하게 하기 위한 옵션을 살펴보겠습니다.
- HTTP Polling
- 여기서 REST 끝점을 사용하여 새 정보가 도착했는지 확인하기 위해 서버에 지속적인 요청이 이루어집니다.
- 따라서 기본적으로 클라이언트는 설정된 빈도로 요청을 하고 많은 요청을 일으키며 종종 서버는 빈 응답으로 돌아옵니다. 따라서 그다지 유익하지 않습니다.
- HTTP Long Polling
- HTTP Polling의 개선 사항은 HTTP Long Polling입니다.
- 여기에서 요청에 대한 응답은 새 데이터가 나타날 때만 반환되며 연결을 유지함으로써 가능합니다.
- 클라이언트에 관한 한 기본 폴링과의 유일한 차이점은 기본 폴링을 수행하는 클라이언트가 서버의 부하를 줄이기 위해 각 요청 사이에 의도적으로 작은 시간 창을 남길 수 있고 다른 가정으로 시간 초과에 응답할 수 있다는 것입니다.
- 하지만 새로운 데이터를 가져오기 위해 매번 새로운 HTTP 요청을 열어야 합니다
- 웹 소켓
- WebSocket 연결은 전송 계층에서 TCP/IP를 사용하여 전이중 연결을 제공합니다.
- 이제 두 통신 당사자가 양방향으로 동시에 메시지를 보낼 수 있습니다.
- 연결은 영구적입니다.
- 즉, 응용 프로그램이 실행되는 동안 열린 상태로 유지됩니다. 연결은 상태 저장(stateful)이기도 합니다.
- 서버가 메시지를 시작하거나 그 반대의 경우도 마찬가지입니다
- HTTP 스트리밍
- HTTP 스트리밍은 웹 서버가 무기한 열려 있는 단일 HTTP 연결을 통해 클라이언트에 지속적으로 데이터를 보낼 수 있도록 하는 푸시 스타일 데이터 전송 기술입니다.
- 기술적으로 이것은 HTTP 규칙에 위배되지만 HTTP 스트리밍은 HTTP를 재발명하지 않고도 서버와 클라이언트 간에 모든 종류의 동적 또는 스트리밍 가능한 데이터를 전송하는 효율적인 방법입니다.
- 지난 몇 년 동안 웹 소켓을 사용했습니다. 클라이언트와 서버가 모두 이벤트 스트림을 사용하여 서로 통신하려는 경우에만 유용하며 정보를 조회만 하고 싶을 경우에는 그렇게 좋은 선택은 아닙니다. 그래서 이러한 문제를 해결하기 위해 W3C에 의해 SSE가 만들어졌습니다.
특징
- 각 알림은 한 쌍의 줄 바꿈(/n)으로 끝나는 텍스트 블록으로 전송됩니다
- 서버는 Flux 형식의 데이터 스트림으로 응답을 보냅니다.
- 브라우저의 단일 요청은 동일한 HTTP(HTTPS) 호출에서 여러 응답(JSON 유형)을 다시 내보냅니다.
- 재연결 기능이 내장되어 있으며, 서버 오류로 인해 연결이 끊어지면 클라이언트는 3초 후에 자동으로 다시 연결을 시도합니다.
- HTTP 스트리밍 측면에서 '느슨하게 정의된' 이전의 표준화인 HTTP 스트리밍을 기반으로 합니다
- 널리 사용되는 브라우저에서 데이터 스트림을 구독하기 위해 JavaScript EventSource API를 사용합니다.
동작 방식
1. 클라이언트는 아래 HTTP 요청 규칙에 맞춰서 서버에게 연결을 요청합니다.
GET /api/v1/live-event
Accept: text/event-stream // 클라이언트가 서버의 이벤트 스트림을 기다리고 있다는 의미
Cache-Control: no-cache // 캐싱을 비활성화하고 영구 연결 요청
Connection: keep-alive // 업데이트를 가져오는 데 사용할 열린 연결을 제공
2. HTTP 연결이 이루어지면 서버는 연결을 유지합니다.
3. 이벤트/데이터를 가져올 때마다 서버는 Flux 형식의 데이터 스트림으로 클라이언트에게 응답을 보냅니다.
- Flux는 데이터를 사용자에게 다시 스트리밍 하는 역할을 하는 객체입니다.
4. 이 과정은 클라이언트가 이벤트 스트림을 중지할 때까지 반복됩니다.
- 이벤트 스트림은 서버 측에서는 닫을 수 없으며, 클라이언트 측에서 닫아야 합니다.
장점
- 전통적인 HTTP를 통해 통신하므로 다른 프로토콜이 필요가 없습니다.
- 재접속 처리 같은 대부분의 저수준 처리가 자동으로 됩니다.
- HTML5 표준 기술답게 IE를 제외한 브라우저 대부분을 지원합니다.
- HTML과 JavaScript만으로 구현할 수 있으므로 현재 지원되지 않는 브라우저(IE 포함)도 polyfill을 이용해 크로스 브라우징이 가능합니다. (여기서 polyfill이란 브라우저가 지원하지 않는 API를 플러그인이나 JavaScript 등으로 흉내 내 구현한 것을 뜻합니다.)
한계점
- HTTP 요청 시 text/event-stream 형식으로 요청해야 하기 때문에 UTF-8로 제한되며 이진 데이터를 지원하지 않습니다.
- 브라우저별로 최대 연결할 수 있는 수가 제한이 있습니다. HTTP/1.1 사용 시 6개, HTTP/2 사용 시 최대 100개까지 유지 가능합니다.
- 서버에서 클라이언트로 단방향 통신만 지원됩니다.
주로 어디에 쓰일까?
- 대량 데이터 다운로드 시 얼마나 남았는지 확인하는 다운로드 진행 상황 표시할 경우
- 라이브 스포츠 점수
- 뉴스 피드
- 주식/암호화폐 업데이트
- 상태 업데이트/알림
- 사용자가 실시간에 가까운 정보를 필요로 하는 모든 경우
마무리
신규 프로젝트에 적용할 EDA(Event Driven Architecture)를 공부하면서 같이 사용할 폴링 기법에 대해 찾아보니 SSE가 보이기에 분석 목적으로 공부를 해봤습니다.
공부를 해보니 양방향으로 통신할 필요가 없는 경우에 사용하면 좋을 거 같다고 생각이 들었으며, 구현에 있어선 웹소켓보다는 쉽게 구현할 수 있겠다고 생각 들었습니다. 하지만, 웹소켓보다 좋을까? 이거에 대한 답은 아직 찾지를 못했네요.
이 부분은 추후에 벤치 테스트를 돌리면서 비교를 해봐야겠다고 생각이 드네요.
아직 부족하거나 틀린 부분이 있을 수도 있으니 주의하시면 좋을 거 같습니다.
이번 포스팅은 마무리하면서 다음 포스팅에서 뵙겠습니다.
참고
WebSockets vs Server-Sent Events
Server Sent Events — Architecture and Implementation
Getting Started with Server-Sent Events and understanding when to use Polling, WebSockets, and SSE
'CS 지식 > 네트워크' 카테고리의 다른 글
IPFS란? (0) | 2021.10.27 |
---|---|
WebRTC 란? (0) | 2021.10.01 |
RTMP(Real-Time Messaging Protocol) 란? (0) | 2021.09.14 |