Server Sent Events#
서버 전송 이벤트(Server-Sent Events, SSE)는 웹 서버가 클라이언트 브라우저로 데이터를 자동으로 푸시할 수 있게 해주는 웹 기술이다. 전통적인 HTTP 통신에서는 클라이언트가 요청을 보내고 서버가 응답하는 방식이었지만, SSE는 서버가 필요할 때마다 자발적으로 데이터를 전송할 수 있는 단방향 통신 채널을 제공한다.
SSE는 HTML5 표준의 일부로, EventSource API를 통해 구현된다. 이 기술은 기존 HTTP 프로토콜 위에서 작동하며, 특별한 프로토콜 전환 없이 실시간 통신이 가능하다는 장점이 있다.
SSE의 핵심 특징#
서버 전송 이벤트는 다음과 같은 주요 특징을 가지고 있다:
단방향 통신
SSE는 서버에서 클라이언트로의 단방향 통신만 지원한다. 클라이언트가 서버로 데이터를 보내려면 별도의 HTTP 요청이 필요하다.
자동 재연결
네트워크 연결이 끊어졌을 때, EventSource 객체는 자동으로 서버와의 연결을 재시도한다. 이는 개발자가 직접 구현할 필요가 없어 편리하다.
표준 HTTP 사용
SSE는 표준 HTTP 프로토콜을 사용하므로 기존 웹 인프라와 호환성이 좋다. 특별한 프로토콜이나 포트가 필요하지 않다.
이벤트 ID 지원
각 이벤트에 ID를 부여할 수 있어, 연결이 끊겼다가 복구될 때 마지막으로 수신한 이벤트 이후부터 데이터를 수신할 수 있다.
이벤트 유형 구분
서버는 여러 유형의 이벤트를 전송할 수 있으며, 클라이언트는 이벤트 유형에 따라 다른 처리를 할 수 있다.
SSE 작동 원리#
SSE의 작동 원리는 다음과 같다:
- 연결 수립: 클라이언트는 EventSource 객체를 생성하여 서버에 연결을 요청한다.
- 지속적인 응답: 서버는
text/event-stream
콘텐츠 유형으로 응답하고, 연결을 열린 상태로 유지한다. - 데이터 스트리밍: 서버는 필요할 때마다 정해진 형식으로 데이터를 스트리밍한다.
- 클라이언트 처리: 클라이언트는 수신된 이벤트를 처리하기 위한 이벤트 리스너를 등록한다.
SSE 메시지 형식#
SSE 메시지는 다음과 같은 간단한 텍스트 기반 형식을 사용한다:
1
2
3
| event: 이벤트명
id: 이벤트ID
data: 실제 데이터 내용
|
각 필드는 선택적이며, 메시지는 빈 줄로 구분된다. 데이터 필드가 여러 줄인 경우 각 줄 앞에 “data:” 접두사를 붙여야 한다.
데이터만 있는 메시지#
이 형식은 data
필드만 포함하며, 가장 기본적인 형태이다.
빈 줄로 메시지가 끝남을 나타낸다.
여러 줄 데이터#
데이터가 여러 줄일 경우 각 줄 앞에 data:
를 붙여야 한다.
1
2
| data: Line 1 of the message
data: Line 2 of the message
|
이름이 있는 이벤트#
event
필드를 사용하여 이벤트 이름을 지정한다. 클라이언트는 특정 이벤트를 수신하도록 설정할 수 있다.
1
2
3
4
5
| event: userconnect
data: {"username": "bobby", "time": "02:33:48"}
event: usermessage
data: {"username": "bobby", "time": "02:34:11", "text": "Hi everyone."}
|
ID와 재연결 시간 포함#
id
필드는 이벤트 ID를 설정하며, 클라이언트가 재연결 시 끊어진 이후의 이벤트를 요청할 수 있다. retry
필드는 재연결 대기 시간을 밀리초 단위로 지정한다.
1
2
3
| id: 12345
retry: 3000
data: {"userId": 1, "status": "online"}
|
혼합형 메시지#
하나의 스트림에서 다양한 필드를 혼합하여 사용할 수 있다.
1
2
3
4
5
6
7
8
| event: userconnect
data: {"username": "bobby", "time": "02:33:48"}
data: Here's a system message of some kind that will get used
data: to accomplish some task.
event: usermessage
data: {"username": "bobby", "time": "02:34:11", "text": "Hi everyone."}
|
SSE 구현 예제#
서버 측 구현 (Node.js with Express)#
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
29
30
31
32
33
34
35
36
37
38
39
40
| const express = require('express');
const app = express();
// SSE 엔드포인트 설정
app.get('/api/events', function(req, res) {
// SSE 헤더 설정
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
});
// 클라이언트에 초기 연결 메시지 전송
res.write('data: ' + JSON.stringify({ message: '연결 수립됨' }) + '\n\n');
// 주기적으로 업데이트 전송 (예: 주식 가격)
const intervalId = setInterval(() => {
const stockData = {
timestamp: Date.now(),
price: Math.random() * 100 + 50
};
// 일반 메시지 형식
res.write('data: ' + JSON.stringify(stockData) + '\n\n');
// 특정 이벤트 유형 지정
res.write('event: stockUpdate\n');
res.write('data: ' + JSON.stringify(stockData) + '\n\n');
}, 5000);
// 클라이언트 연결 종료 시 정리
req.on('close', () => {
clearInterval(intervalId);
console.log('클라이언트 연결 종료');
});
});
app.listen(3000, () => {
console.log('SSE 서버가 포트 3000에서 실행 중입니다.');
});
|
클라이언트 측 구현 (JavaScript)#
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
29
30
31
32
| // EventSource 객체 생성
const eventSource = new EventSource('http://localhost:3000/api/events');
// 기본 메시지 이벤트 처리
eventSource.onmessage = function(event) {
const data = JSON.parse(event.data);
console.log('새로운 데이터 수신:', data);
updateUI(data);
};
// 특정 이벤트 유형 처리
eventSource.addEventListener('update', function(event) {
const updateData = JSON.parse(event.data);
console.log('업데이트 이벤트:', updateData);
handleUpdate(updateData);
});
// 연결 열림 이벤트
eventSource.onopen = function() {
console.log('SSE 연결이 수립되었습니다.');
};
// 오류 처리
eventSource.onerror = function(error) {
console.error('SSE 연결 오류:', error);
// 필요시 추가 오류 처리 로직
};
// 연결 종료 (필요시)
function closeConnection() {
eventSource.close();
}
|
실시간 API에서 SSE의 활용 사례#
SSE는 다음과 같은 실시간 애플리케이션 시나리오에서 특히 유용하다:
뉴스 피드 및 소셜 미디어 업데이트
새로운 기사, 트윗, 댓글 등이 게시되면 실시간으로 사용자에게 알린다.
주식 시장 및 금융 데이터
주가, 환율, 암호화폐 가격 등의 실시간 업데이트를 제공한다.
스포츠 경기 실시간 중계
득점, 경기 상태 변경 등의 정보를 실시간으로 전달한다.
모니터링 대시보드
서버 성능, 네트워크 상태, 사용자 활동 등을 실시간으로 모니터링한다.
알림 시스템
사용자에게 중요한 이벤트, 메시지, 경고 등을 즉시 알린다.
SSE API 설계 시 고려사항#
이벤트 구조 설계
- 명확한 이벤트 유형과 데이터 구조 정의
- 일관된 형식 사용 (보통 JSON)
- 이벤트별 고유 ID 부여
확장성
- 다수의 클라이언트 연결 처리 방안
- 메모리 및 CPU 사용량 최적화
- 메시지 큐 시스템 연동 고려 (Redis, Kafka 등)
보안
- 인증 및 권한 검증 메커니즘
- HTTPS 사용
- 민감한 데이터 전송 시 암호화 고려
오류 처리
- 연결 끊김 시나리오 처리
- 재연결 전략 구현
- 중복 이벤트 처리 방안
성능 최적화
- 이벤트 배치 처리
- 적절한 폴링 간격 설정
- 불필요한 이벤트 필터링
SSE 제한 사항 및 해결 방안#
제한 사항#
- 단방향 통신만 가능: 클라이언트에서 서버로의 데이터 전송이 불가능하다.
- 브라우저별 연결 제한: 대부분의 브라우저는 도메인당 HTTP 연결 수를 제한한다.
- 해결책: 여러 하위 도메인 사용 또는 연결 통합
- IE 지원 부재: 인터넷 익스플로러는 SSE를 지원하지 않는다.
- 프록시 처리: 일부 프록시는 장시간 지속되는 연결을 중단할 수 있다.
- 해결책: 연결 타임아웃 설정과 자동 재연결 구현
SSE를 활용한 실시간 API 설계 사례#
실시간 알림 API 설계 예시#
- 엔드포인트 구조:
/api/notifications/stream
- 알림 스트림 엔드포인트/api/notifications/read
- 알림 읽음 처리 엔드포인트 (일반 HTTP POST)/api/notifications/preferences
- 알림 설정 엔드포인트 (일반 HTTP GET/PUT)
- 이벤트 유형:
system
- 시스템 알림message
- 새 메시지 알림update
- 콘텐츠 업데이트 알림alert
- 중요 경고 알림
- 인증 및 권한:
- 쿠키 또는 토큰 기반 인증
- 사용자별 알림 필터링
- 권한에 따른 알림 범위 제한
- 확장성 고려:
- Redis PubSub을 통한 여러 서버 인스턴스 간 이벤트 동기화
- 사용자별 연결 풀 관리
- 데이터베이스 부하 감소를 위한 캐싱 전략
주요 라이브러리 및 도구#
클라이언트 측#
- EventSource 폴리필: IE 등 지원하지 않는 브라우저를 위한 폴리필
- RxJS: 반응형 프로그래밍을 통한 이벤트 스트림 처리
- Axios SSE: Axios 기반 SSE 클라이언트
서버 측#
- Node.js:
event-stream
패키지 - Express: SSE 미들웨어
- Flask-SSE: 파이썬 Flask 프레임워크용 SSE 확장
- Spring 5+: SSE 네이티브 지원
용어 정리#
참고 및 출처#
Server-Sent Events vs. Webhook 실시간 애플리케이션을 개발할 때 서버와 클라이언트 간의 효율적인 통신 방식을 선택하는 것은 매우 중요하다. 서버 전송 이벤트(Server-Sent Events, SSE)와 웹훅(Webhook)은 모두 서버에서 클라이언트로 데이터를 전달하는 방법이지만, 그 작동 방식과 적합한 사용 사례가 크게 다르다.
서버 전송 이벤트(SSE) 기본 개념 서버 전송 이벤트(SSE)는 HTTP 연결을 통해 서버에서 클라이언트로 단방향 실시간 이벤트 스트림을 전송하는 기술이다. HTML5 표준의 일부로, 웹 브라우저에서 EventSource API를 통해 구현된다. SSE는 표준 HTTP 프로토콜 위에서 작동하며, 별도의 프로토콜 전환 없이 실시간 데이터 푸시가 가능하다.
...
Server-sent Events vs. Websocket 웹 애플리케이션이 점점 더 실시간적이고 동적으로 발전함에 따라, 서버와 클라이언트 간의 효율적인 통신 방식이 중요해졌다. 전통적인 HTTP 요청-응답 모델은 실시간 데이터 전송에 최적화되어 있지 않기 때문에, 이를 보완하기 위한 기술로 서버 전송 이벤트(Server-Sent Events, SSE)와 웹소켓(WebSocket)이 등장했다. 두 기술 모두 실시간 통신을 가능하게 하지만, 그 작동 원리와 적합한 사용 사례에는 중요한 차이가 있다.
서버 전송 이벤트(SSE) 개념과 작동 원리 서버 전송 이벤트(SSE)는 HTTP 연결을 통해 서버에서 클라이언트 브라우저로 데이터를 단방향으로 스트리밍하는 웹 기술이다. HTML5 표준의 일부로, EventSource API를 통해 구현된다. SSE는 기존 HTTP 프로토콜을 활용하며, 특별한 프로토콜 전환 없이 서버에서 클라이언트로의 실시간 데이터 푸시가 가능하다.
...