◎ 기술 도입 필요성
- 주로 웹 통신간에 사용하는 http는 기본적으로 비연결성, 무상태성이라는 특징을 가짐
- 알림을 도입하기 위해서는 서버에서 일방적으로 정보를 전달해주어야 하므로 단순한 http로 구현하기에는 무리가 있다.
◎ 알림을 구현할 수 있는 기술들
폴링(Polling)
- 클라이언트에서 주기적으로 평범한 Request를 전송해 알림이 왔는지 확인한다.
- 단점
- 클라이언트가 지속적으로 Request를 전송하므로 서버의 부담을 준다.
- Connection을 맺고 끊는 것에 많은 서버의 자원을 사용함
- 주기적으로 알림이 왔는지 확인하므로 실시간이라고 보기 어렵다.
웹 소켓(WebSocket)
- 프로토콜의 일종, 클라이언트와 서버 간의 효율적인 양방향 통신을 실현하기 위한 구조
- 양방향 통신으로 진행
- 최초 접속이 일반 Http 요청을 이용한 Handshaking으로 이루어진다.
- 웹소켓 포트에 접속해 있는 모든 클라이언트에게 이벤트 방식으로 응답
- 장점
- 최초 접속시(http 이용시)에만 헤더 정보를 보내고 더 이상 헤더 정보를 보내지 않음
- 계속적으로 Connection을 열어두고 있다가 바로 그에 대한 결과값을 받기에 실시간성이 보장
- 단점
- EC2 프리티어를 이용하여 사용하기에는 무리일 수 있다.
- 양방향 통신에 적합한 방식이므로 알림 서버스에서는 적합하지 않음
SSE(Server-Sent-Events)
- HTTP 스트리밍을 통해 서버에서 클라이언트로 단방향의 Push Notification을 전송할 수 있는 HTML5 표준 기술
- 웹소켓과 달리, 클라이언트는 서버로부터 데이터만 받을 수 있다.
- 별도의 프로토콜을 사용하지 않고 HTTP 프로토콜만으로 사용
- 장점
- HTTP 프로토콜만으로 사용이 가능하기에 훨씬 가볍다.
- 단점
- 접속에 문제가 있으면 자동으로 재연결을 시도하지만 클라이언트가 페이지를 닫아도 서버에서 감지하기가 어렵다.
◎ 알림을 SSE로 구현한 이유
- EC2 프리티어를 사용하기 때문에 계속 연결되어 있는 WebSocket 보다는 SSE가 서버에 부담을 덜 줄 수 있다고 생각함
- Frontend 멘토님께도 자문을 구하였더니 SSE를 추천함
- 후순위에 구현하려 했던 채팅기능까지 고려한다면 WebSocket을 사용할 수 있었겠지만, 다양한 기술을 사용해 보고 싶어 SSE를 선택함
◎ 기술적으로 어려웠던 부분 & 해결
- 어려웠던 부분
- 클라이언트가 서버의 이벤트를 구독하고 있는 동안 TimeoutException이 발생함
- DB와 서버를 연결하는 Connection 수의 제한이 있어 다른 API들이 DB에 접근하지 못하였다.
- 해결 방안
- 서버와 DB에서 연결할 수 있는 Connection 수를 늘림
- Transactional 설정을 readOnly=true 로 변경함
- 어려웠던 부분
- 클라이언트에서 구독 시에 Header에 토큰 값을 실어서 보낼 수 없어 인증을 할 수 없었음
- 해결방안
- 구독하기 전에 인증할 수 있는 api를 만들고, Response로 구독 식별자를 보냄
- 구독시에 식별자 값을 보내 구독할 수 있는 식별자인지 확인하고 그렇지 않으면 Exception을 발생시킴