| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
- 리액트
- 모던 자바스크립트 딥 다이브
- 공식문서
- 프로그래머스
- 자료구조
- react
- 모던 딥 다이브 자바스크립트
- 알고리즘
- 프론트엔드
- useMemo
- CSS
- Github
- 개발자취업부트캠프
- 비전공자
- 코딩테스트
- JavaScript
- 내일배움카드
- styled-components
- 자바스크립트
- 메가바이트스쿨
- 패스트캠퍼스
- 입문
- TypeScript
- 개발 공부
- next.js
- useRef
- 국비지원교육
- MegabyteSchool
- GIT
- 이벤트
- Today
- Total
개발 기록 남기기✍️
Polling / Long Polling / Server-Sent Events / WebSocket 본문

서버의 event를 클라이언트로 보내는 4가지 방법이 있는데, 미니 프로젝트를 진행하면서 실시간 알림 기능 구현을 위해 SSE(Server Sent Events)를 활용했다. 각각의 방법을 살펴보고, 왜 내가 SSE를 채택하게 되었는지에 대해서 기술하고자 한다.
🔔 Polling

클라이언트가 주기적으로 서버에 데이터 요청을 보내는 프로세스이다. 이 방식으로 클라이언트는 최신 정보를 유지할 수 있다.
폴링은 이해하고 구현하기 쉬운 단순한 형태이며, HTTP 같은 범용적인 프로토콜을 사용하기 때문에 다양한 플랫폼과 기기에서 활용하기 좋다.
폴링을 사용하는 예시로는, IoT 장치가 있다. IoT 장치들은 주로 센서를 통해 데이터를 수집하고 이를 중앙 서버나 클라우드에 전송한다.
스마트 홈에서 폴링을 활용하여 센서(온도, 습도, 조명, 모션 등)의 상태를 주기적으로 확인하고 이를 통해 조명을 제어하거나 에어컨을 켜거나 끄는 등의 액션을 취한다.
JavaScript에서 setTimeout 혹은 setInterval 함수를 사용해서 폴링을 구현할 수 있다.
Polling의 단점
폴링은 필요하지 않은 상황에서도 계속해서 서버에 요청을 보내는 행위이기 때문에 효율적이지 못하고, 클라이언트가 많아질 수록 서버의 부담이 커진다. 또한 http 오버헤드가 발생한다는 단점이 있다.
HTTP Overhead : 정보의 신뢰성 판단을 위한, 보내지는 헤더 같은 정보 때문에 오히려 데이터량이나 처리시간이 증가하는 것
🔔 Long-polling

롱 폴링은 서버 측에서 접속을 열어두는 시간을 길게 하는 방식으로 앞의 폴링을 개선한 방식이다.
[롱 폴링 작동 방식]
- 클라이언트에서 서버로 http request를 날린다.
- 서버에 응답에 대한 사용 가능한 데이터가 없으면 계속 기다리다가 서버에서 해당 클라이언트로 전달할 이벤트가 있다면 그 순간 response 메시지를 전달하면서 연결이 종료된다.
- 클라이언트에서는 곧바로 다시 http request를 날려서 서버의 다음 이벤트를 기다린다.
Long-polling의 단점
일반 폴링 방식보다는 서버의 부담이 줄겠지만, 만약 서버에서 클라이언트로 보내는 이벤트들의 시간 간격이 좁다면 polling과 별 차이가 없게 되며, 다수의 클라이언트에게 동시에 이벤트가 발생될 경우에는 곧바로 다수의 클라이언트가 서버로 접속을 시도하면서 서버의 부담이 급증하게 된다.
🔔 Websocket

웹소켓은 양방향 채널을 이용해 채팅방처럼 양방향 통신이 가능하다.
기존 http 요청 응답 방식은 요청한 그 클라이언트에만 응답이 가능했는데, ws 프로토콜을 통해 웹소켓 포트에 접속해있는 모든 클라이언트에게 이벤트 방식으로 응답한다.
최초 접속이 일반 http request를 통해 handshaking 과정을 통해 이루어지기 때문에, 기존의 80, 443 포트로 접속하므로 추가로 방화벽을 열지않고도 양방향 통신이 가능하고, http 규격인 CORS 적용이나 인 증 등의 과정을 기존과 동일하게 가져갈 수 있는 것이 장점이다.
Socket.io : node.js 기반으로 만들어진 기술로, 자체 스펙으로 만들어진 socket.io 서버를 만들고 socket.io 클라이언트와 브라우저에 구애받지 않고 실시간 통신 가능해짐
Websocket 단점
websocket 프로토콜을 처리하기 위해서는 전이중 연결과 새로운 웹소켓 서버가 필요하다. 따라서 구현하는 비용이 많이 든다는 단점이 있다.
🔔 SSE(Server-Sent Events)

SSE는 서버의 데이터를 실시간으로, 지속적으로 Streaming하는 기술이다. 웹 표준으로써 IE를 제외한 모든 브라우저에서 지원되며, IE 역시 polyfill을 통해 지원이 가능하다.
websocket과 같이 양방향이 아닌 server -> client 단방향이기에 서버의 event나 message를 client로 push하는 작업에 유용하게 사용될 수 있다.
어느 정도 웹소켓의 역할을 하면서 더 가볍다. 그리고 양방향이 아니기에 요청 시 ajax로 쉽게 이용할 수 있고 HTTP API 만으로 동작되며 구현도 간단하기 때문에 서버와 프론트엔드 양측 모두 매우 쉽게 개발이 가능하다.
Server Sent Event 특징
- 브라우저는 서버가 생성한 Stream을 계속 받음(Read Only)
- 응답/요청 시에만 헤더를 사용하고 나머지는 청크 단위 데이터를 보내기 때문에 HTTP 헤더로 인한 오버헤드가 거의 없음
- Connection 유지를 위해 HTTP protocol을 사용, HTTP/2를 통한 multiplexing 가능
- multiplexing : 두개 이상의 저수준의 채널들을 하나의 고수준 채널로 통합하는 과정
- 연결이 끊어지면 EventSource가 오류 이벤트를 발생시키고 자동으로 다시 연결을 시도(error recovery)
클라이언트는 서버로부터 수신받기만 하는 구조이기 때문에 주로 피드 구독, 뉴스 업데이트 또는 알림에 사용된다.
🥊 WebSocket vs Server-Sent Events

| Socket | Server-Sent Events | |
| 브라우저 지원 | 대부분 브라우저에서 지원 | 대부분 모던 브라우저 지원(polyfills 가능) |
| 통신 방향 | 양방향 | 단방향(서버 -> 클라이언트) |
| 리얼타임 | O | O |
| 데이터 형태 | Binary, UTF-8 | UTF-8 |
| 자동 재접속 | X | O(3초마다 재시도, 시간 설정 가능) |
| 최대 동시 접속 수 | 브라우저 연결 한도는 없지만 서버 셋업에 따라 다름 | HTTP를 통해서 할 때는 브라우저 당 6개까지 가능 HTTP2로는 100개가 기본 |
| 프로토콜 | websocket | HTTP |
| 배터리 소모량 | 큼 | 작음 |
| 방화벽 친화적 | X | O |
RealTime Web : 인터넷에서 사용자들로 하여금 창작자가 정보를 만들어내는 즉시 수신할 수 있는 기술을 말한다.
웹소켓은 주로 리얼타임이 필요한 곳에서 많이 사용된다.
- 카카오톡 채팅(SSE와 HTTP로도 만들 수는 있음)
- 주식 트레이딩 데이터
- 크립토 실시간 차트
SSE는 알람을 줄 때 많이 사용된다. 클라이언트에서는 데이터를 받기만 하면 되고 완전히 실시간일 필요는 없기 때문이다.
- Twitter에서 피드를 받을 때
- 페이스북에서 친추 요청을 받았을 때
알람 기능을 웹소켓으로도 충분히 구현할 수도 있지만, 자동 재연결 기능이라던지, 배터리 소모량이라던지 여러모로 다른 특징 때문에 나뉘어 사용되는 편이다.
클라이언트에서 SSE 기능 구현하기
모던 웹 브라우저에서는 SSE를 쉽게 사용할 수 있도록 기본적으로 EventSource API를 제공한다.
서버에서 업데이트된 내용이 푸시되면 onmessage 함수가 실행되고 et.data 속성에서 데이터를 사용할 수 있다.
// 이벤트를 전달 받기 위해서 서버로 접속을 시작하려면 우선, 이벤트를 생성하는 서버측 스크립트를 URI로 지정하여 새로운 EventSource 객체를 생성한다
// EventSource 생성자에 전달 된 URL이 절대 URL 인 경우 해당 출처 (scheme, domain, port)가 호출 페이지의 출처와 일치해야 한다.
const eventSource = new EventSource(`/subscribe`); // sse코드가 있는 서버단 파일
// 서버로부터 데이터가 오면
eventSource.addEventListener('message', function(e) {
console.log(e.data);
});
// connection되면
eventSource.addEventListener('open', function(e) {
// Connection was opened.
});
// error 나면
eventSource.addEventListener('error', function(e) {
if (e.readyState == EventSource.CLOSED) {
// Connection was closed.
}
});
이벤트를 생성하는 스크립트가 다른 도메인에 존재할 경우엔 URI와 옵션 딕셔너리를 모두 지정하여 새로운 EventSource 객체를 생성한다.
연차/당직 관리 프로젝트를 하면서, 유저에게 신청 처리 결과를 알림으로 보내주는 기능을 구현했다. 동시에 신청 처리 결과를 모두 보여주되, 미확인한 알림만 보여주도록 하이라이팅 처리를 해야했다.
이를 구현하기 위해서 웹소켓을 쓰면 더 좋지 않은가? 하는 질문이 들어올 수도 있겠지만, 백엔드와 프론트엔드 모두 웹소켓 환경을 위한 설정을 해야하고, 알람 자체가 유저는 서버에게 데이터를 전송할 필요없이 받기만 하는 구조였다.
또한 자동 재접속이 되어 클라이언트 측에서 별도의 처리를 하지 않아도 되고, 이로 인해 유저가 불편함을 겪지 않아도 된다는 점이 메리트로 느껴져서 SSE를 사용하게 되었다.
기회가 된다면 웹소켓도 배워서 실시간 채팅 기능을 구현해보고 싶다..!
'Front-End > 기초 지식' 카테고리의 다른 글
| Feature Sliced Design 그게 뭔데.. (0) | 2025.03.01 |
|---|---|
| [HTTP 인증] 쿠키, 세션 그리고 토큰(feat. JWT) (1) | 2023.07.17 |
| [Web] LocalStorage, SessionStorage, Cookie (0) | 2023.05.19 |
| [Front-End] SSR과 CSR의 개념(feat. Next.js) (1) | 2023.04.01 |