서버 → 클라이언트 통신
특징
- 서버쪽에서 클라이언트에게 지속적으로 스트리밍 하는 기술
- HTTP 1.1 에
Persistent Connections
Chunked Transfer Encoding
, 기술 이용Persistent Connections
:- 지속연결기능 (
Connection: keep-alive
해더)
- 지속연결기능 (
Chunked Transfer Encoding
:- 서버에서 데이터를 여러번 걸쳐서 보낼 수 있게 해주는 기술
WebSocket 대비 장 단점
결론적으로 SSE는 최적화, 안정성, 베터리 소모 부분에서 우월함을 가진다.
따라서 굳이 구현하려는게 서버쪽에서만 데이터를 보내줘야하는 서비스는 SSE 로 구현 하자
단점
- 서버 쪽 단방향 통신
- 요청 시 데이터를 보내는건 가능
- 바이너리 데이터 전송 불가 (Base64로 변환 해야함)
장점
- WebSocket 은 전용 서버를 따로 구축해야한다는 문제가 있는데
SSE는 해더 설정 한번이면 끝 - 서버와 연결이 끊길이 3초마다 재접속 시도
- 최적화 배터리 소모량 부분에서 좋음
구현
서버
- 보낼 때 아예 응답을 보내서 커넥션을 종료하면 안되고
일부 데이터 스트림을 보내주는 함수를 쓰자
해더 구성
Content-Type
을text/event-stream
으로 설정 하기만 하면됨GET /SSE HTTP/1.1 Content-Type: text/event-stream Cache-Control: no-cache Connection: keep-alive
Connection: keep-alive
: 커넥션 유지Cache-Control: no-cache
브라우저에서 케싱 하지 않게끔
메시지 구조
event: message\n\n
data: 보낼데이터\n\n
event
: 기본값 (message)- 클라이언트에 보낼 이벤트 지정
- 클라이언트는 해당 이벤트에 맞춰 이벤트 리스너를 구성
data
:- 해당 부분에 보낼 메시지 입력하면됨
- UTF-8 만 지원
\n\n
:- 줄바꿈을 두 번 한걸 표현하기 위해서 둠
- 실제 코드짤때 표현 한 것처럼
\n\n
으로 줄바꿈 두번 해야함
클라이언트
- 여기선 js로 구현
// SSE 클라이언트 객체 생성
const eventSource = new EventSource(`/sse`);
// 서버로부터 데이터가 오면
eventSource.addEventListener("message", (e) => {
console.log(e.data);
});
// 만일 서버쪽에서 event: notification 으로 설정하면 해당 리스너에서 받을 수 있다
/* eventSource.addEventListener("notification", (e) => {
console.log(e.data);
}); */
// connection되면
eventSource.addEventListener("open", (e) => {
console.log("SSE 서버연동");
});
// error 나면
eventSource.addEventListener("error", () => {
if (e.readyState === EventSource.CLOSED) {
console.log("서버 중단");
}
});
사용 예
- 주식 실시간 호가
- 클라이언트 쪽에서는 종목 코드 하나만 보내주면 따로 보낼 데이터는 없기에
- 실시간 채팅
- 채팅방 아이디를 식별자로 가져서 요청하여 모든 메시지를 서버쪽에서 스트리밍 받게 설계