Push 알림 기능 개발기 (4) ‐ SSE 방식의 문제점 - YJGwon/connectruck GitHub Wiki
SSE + Redis Pub/Sub 방식의 문제점
브라우저 열려있을 때만 동작
페이지 내 javascript 코드로 알림 기능이 동작하기 때문에 웹 페이지를 닫으면 알림을 받을 수 없다. 이는 service worker를 통해 해결할 수 있다. javascript 파일을 service worker로 등록하면 브라우저에서 백그라운드로 실행된다. 그러나 이 방식으로도 해결할 수 없는 더 큰 문제가 있다.
server connection 고갈
SSE를 통한 push 알림 전송을 위해서는 서버와 클라이언트가 TCP conenction을 유지하고 있어야 한다. 현재 connectruck은 하나의 application으로 구성되어 있는데, 알림 발송 서비스를 별도의 서버로 분리하지 않으면 SSE 통신을 위한 connection 유지가 전체 서비스에 영향을 끼칠 수 있다.
이는 사용자의 browser에 service worker를 등록할 경우 더더욱 우려되는 부분인데, 알림을 받는 사용자가 페이지를 닫은 후에도 계속 connection을 제공해야 하고 이를 주기적으로 해제하지 않으면 점점 더 많은 connection이 점유되어 결국 connection이 모자르게 될 수도 있다.
정말 FCM 도입 외엔 해결할 방법이 없었나?
위에서 언급했듯이 별도의 알림 서버를 분리할 수도 있고, connectruck은 특정 행사 기간 동안 사용하는 서비스로 기획했기 때문에 행사 일정이 끝난 후 해당 행사와 관련된 알림 connection을 닫아줄 수도 있다. 그러나 알림 발송 기능이 이 서비스의 주 도메인이 아니며 사실 실제 서비스라면 진즉에 FCM을 썼을 것 같아서… 직접 구현해보려는 욕구와 기능 안정성 중 후자를 택하기로 했다(사실 앞서 개발해보며 구현 욕구를 어느정도 충족하기도 했다).
해결책 - FCM 도입
Firebase Cloud Messaging(FCM): iOS, Android, Web 등 다양한 환경에서 메시지를 무료로 전송할 수 있는 크로스 플랫폼 메시징 솔루션
브라우저 열려있을 때만 동작
FCM에서 제공하는 js client용 SDK의 API를 이용해 service worker를 등록할 수 있다. 이를 통해 사용자가 브라우저를 닫아도 push 알림을 보여줄 수 있다. 또 client 기기가 인터넷에 연결되어있지 않는 등 메시지를 발송할 수 없는 상황이 되면 FCM 서버에 메시지가 최대 4주(default 4주) 보관되었다가 재발송된다(참고). 사용자가 브라우저를 닫아도, 오프라인 상태여도, 안정적으로 push 알림을 전달할 수 있다.
server connection 고갈
connectruck의 server는 FCM의 server에 메시지 발송 요청을 하기만 하면 그 다음은 FCM server에서 처리해준다. client는 FCM server와 connection을 유지하게 되어 connectruck의 server는 알림 기능의 부담으로부터 자유로워진다!