SSE를 선택한 이유(결론!)
- 알림은 단방향 통신만을 필요로 하는데 굳이 TCP연결을 유지하며 양방향 통신하는 Websocket을 사용해야 할 이유가 없기 때문에 SSE를 택했습니다.
실시간 데이터 전송 기술
Polling
- HTTP연결의 특성인 stateless와 connectionless탓에 클라이언트는 서버의 실시간 변동 사항을 알 방법이 없습니다.
- 이를 극복하기 위한 Polling방식은 일정 주기를 가지고 HTTP요청을 날려서 서버가 클라이언트로 보낼 메시지가 있는지 확인하는 방식입니다.
Long polling
- 위 polling방법은 일정 주기마다 요청을 보내야하기 때문에 HTTP 오버헤드가 증가하는 문제가 발생합니다.
- 또한, 완전한 실시간을 지원하지 않는다는 문제도 존재합니다.
- 이를 보안하기 위한 Long polling방식은 Http요청의 응답이 올 때까지로 생명 주기를 늘립니다. → 즉 이벤트가 발생할 때 까지 대기하다가 메시지가 생기면 그 때 응답하는 방식입니다.
Sever side event
- 위 Long polling방식은 매 요청마다 새로운 HTTP연결을 해야 하기 때문에 만약 서버에서 데이터를 전송해야 될 경우가 잦아질 경우 서버 부하가 증가할 수 있습니다.
- SSE방식은 지속적인 단일 HTTP 연결을 사용하며 이를 통해 3-way-handshake과정을 반복하지 않고 HTTP 헤더 또한 재 전송하지 않기 때문에 서버 부하를 줄일 수 있습니다.
Websocket
- SSE방식은 서버 → 클라이언트 단방향 통신만 가능한데 Websocket을 사용하면 첫 HTTP연결 후 TCP연결을 설정하기 때문에 실시간 양방향 통신이 가능해집니다.
SSE방식과 Websocket 성능 차이
(Websocket만으로도 구현이 가능할텐데 SSE를 굳이 왜 써야할까!)
- TCP연결은 연결을 유지하기 위한 지속적인 핑/퐁 매커니즘이 동작하는데 SSE방식은 HTTP연결이 수립된 이후부터는 데이터가 올 때까지 기다리기만 하기 때문에 비교적 자원 소모량이 적습니다.
- 또한 HTTP연결 이후 TCP연결을 설정하는 handshake과정이 필요없기 때문에 약간의 성능적 이점이 있을 수 있습니다.
공용 소켓과 개인 소켓에 대한 고민
개인소켓 연결
- 사용자별로 요청을 보내줘야함 -> 서버 리소스 소모 증가
공용소켓 연결
- 알림을 공용소켓에 한번만 쏴줘도됨 -> 서버 리소스 소모 감소
- 알림 개인화 어려움 -> 클라이언트 단에서 연결 돼 있는 사용자들에게 분배
고민
→ 프로젝트에서 알림의 개인화를 위해 사용자 별 개인 소켓을 이용하고 있는데 알림이 모든 사용자를 대상으로 생성된다면 연결이 끊긴 사용자에게도 불필요한 요청이 가지 않을까!?
ex) 모든 사용자에 대한 알림 생성 → 모든 사용자의 소켓(연결이 끊겨도)으로 알림 전송
해결
→ 핑/퐁 매커니즘을 주기적인 연결상태 관리 -> 연결이 끊긴 사용자에게는 보내지않음(낭비X)