서론
서비스 워커는 웹 어플리케이션,브라우저 와 네트워크 사이에 위치한 프록시 서버처럼 동작합니다.
만약 네트워크가 불가능한 상황이라면 캐시 데이터를 사용하거나, 프로세스가 열려있지 않을 때 백그라운드 작업을 하는 등 훌륭한 오프라인 경험을 만들어 냅니다.
서비스 워커를 활용한 대표적인 기술은 MSW 나 PWA 가 있습니다.
백그라운드에서 동작한다는 점에서 앱의 전유물이던 푸시알림도, 브라우저에서 구현할 수 있는데, 간단한 예시로 한번 정리해보려합니다.
아키텍처
큰 틀은 아래 그림과 같습니다.
클라이언트는 service worker 를 등록과 동시에 메인 스레드에서 push 이벤트를 구독하고, 그 구독정보를 서버로 전달합니다.
서버는 구독자 정보를 저장하고, 원할때 원하는 클라이언트에게 메세지를 전송할 수 있습니다.
* 이때 구독 정보는 고유합니다.
이때 클라이언트는 등록만 할것이 아니라, service worker 에서 메세지를 수신할 때 동작을 정의해주어야합니다.
서버는 클라이언트가 오프라인 상태라도 구독 정보를 가지고 있기 때문에, 해당 클라이언트를 타겟팅할 수 있습니다.
클라이언트의 service worker 는 백그라운드에서 "push" 이벤트를 수신하고 있고, 이벤트가 발생하면 showNotification() 을 호출하여, 푸시알림을 띄웁니다.
클라이언트 코드 예제
1. 클라이언트는 서비스워커를 지원하는지 확인합니다.
2. sw.js 파일을 생성하고 등록합니다.
3. 등록후 반환하는 객체의 pushManager.subscribe() 로 서버의 푸시알림을 구독합니다.
5. 구독후 반환값은 http 요청으로 서버로 전송합니다.
service worker 파일은 서버로 부터 push 메세지가 도착했을때, 어떤 행동을할지, 클릭시 어떤 행동을 할지 정의합니다.
1. push 이벤트가 발생하면 event.data.text() 를 추출하여 JSON.parse() 로 객체로 파싱합니다. (이때 data 의 타입은 서버에서 전달하는 JSON 데이터입니다)
2. event.waitUntil(promise) 는 서비스 워커에서 프로미스 작업이 안전하게 진행할 수 있도록 제공해주는 메서드입니다. 해당 메서드의 인자로 알림을 띄우는 promise 를 전달합니다.
3. showNotification(title,options) 으로 필수 파라미터와 필요한 data 도 함께 담아줍니다.
4. notificationclick 이벤트는 위에서 생성한 알림 이벤트 가 인자로 들어옵니다. 클릭했을 때 해당 링크를 열도록 동작시킵니다.
서버 코드 예제
서버에서 서비스 워커로 메세지를 보내기위해서는 복잡한 암호화 작업이 필요합니다.
이 과정을 간단히 처리하기 위해서 web-push 라이브러리를 사용합니다. (*서버는 express 사용)
1. 먼저 메세지를 보내기위해서는 publicKey, privateKey 두개가 필요합니다. 전송할 때마다 포함해야하는데, webpush 라이브러리를 사용해서 세팅을 한번해주면, 자동으로 포함되도록 해줍니다.
* VAPIDKeys 는 단한번만 생성해주면 되기 때문에, 한번 생성하면 별도의 .js 혹은 .json 파일로 저장한 후 사용합니다.
2. 클라이언트에서 구독정보를 받아서 저장할 수 있도록 api 하나를 열어줍니다.
3. 이제 서버에서 알림을 보내는 예제 api 하나만 작성합니다.
여기서 TTL 은 대상이 오프라인일 경우, 백그라운드에 저장할 시간입니다. 예시에서는 12시간동안 보관하고, 이후에 삭제하도록 하였습니다.
순서대로 잘 따라오셨다면, /send api 를 호출할 때마다 브라우저에 푸시알림이 잘 뜰겁니다 :)
그리고 service worker 는 한번 등록되면 수동으로 등록을 제거해주지 않으면 변경사항이 반영되지 않으니,
개발할 때는 Application > Service workers 에서 Update on reload 를 체크해서, 매번 새로 등록할 수 있도록 해줍니다.
'FE > browser' 카테고리의 다른 글
[browser] Cookie (0) | 2023.10.06 |
---|---|
[browser] Blob 다루기 (0) | 2023.10.05 |
[Browser] Web Worker 와 Service Worker (0) | 2023.09.20 |
[Broswer] EventTarget 과 Event, CustomEvent (0) | 2023.09.20 |
[Browser] window.addEventListener (0) | 2023.09.20 |