기기에 설치가 가능
- 브라우저 탭이 아닌 독립 실행형 창오프라인
, 저속도 환경에서도 동작동기화
푸시 알림
기능WEB API
사용으로 네이티브 앱과 같은 사용성을 갖추어야 함HTTPS 프로토콜
을 통한 제공연결 독립적인 항목으로 브라우저가 백그라운드에서 실행하는 스크립트, 웹 페이지와는 별개로 작동한다. 즉 사용자의 기기가 오프라인일 때 이를 사용할 수 있도록,,,
메인 js 코드와 독립된 스레드에서 실행하며 DOM 구조에 대한 어떠한 접근도 갖지 않음
Service Worker는 오프라인 기능 제공 외에도, 네트워크 요청을 제어하고 수정하고, 캐시로부터 반환된 커스텀 응답을 제공하거나 응답을 가공하기도 한다.
install
이벤트self.addEventListener('install', function(e) {
console.log('[Service Worker] Install');
});
캐시를 초기화하고 오프라인 사용을 위한 파일들을 추가
리소스를 캐싱하고 작업하는 경우 시간이 더 소요되는데 event.waitUntil()
을 통해 작업이 설치 작업이 마무리될 때까지 설치 단계를 연장
self.skipWaiting()
을 통해 기존에 설치된 워커를 건너뛰고 현재 제어되고 있는 클라이언트가 닫힐 때까지 대기하지 않고 새 워커를 활성화
wait
서비스 워커가 설정을 완료하고 기존의 다른 워커를 사용히는 클라이언트가 닫힐 때까지 대기
Active
다른 서비스 워커가 제어하고 있는 클라이언트가 없다.
self.clients.claim()
을 통해 열려 있는 클라이언트를 다시 로드하지 않고 본 서비스 워커가 바로 제어네이티브 앱이 Java
, Swift
와 같은 언어로 푸시 알림을 구현하는 것과 달리, PWA는 자바스크립트만으로도 구현이 가능하다
서비스 워커가 브라우저를 백그라운드에서 실행시키기에, 푸시 알림을 구현 할 수 있도록 함
Pull
클라 -> 서버로 데이터 요청 후 서버로부터 데이터를 직접 가져오는 방식
XMLHTTPRequest(axios, ajax)
등의 요청을 보내서 직접 데이터를 받아와야 한다.
Push
클라이언트가 데이터를 요청하지 않아도 중앙 서버에서 알아서 전송 요청을 보내는 방식
FCM, APNs
등 클라우드 메시징 서비스를 사용
어플리케이션 서버와 푸쉬 서버가 각각 분리되어 있는 구조
따라서, 어플리케이션 서버는 푸시 알림에 대한 리소스 자원에 대해 자유롭기에 부담이 적고 본 기능에 집중할 수 있다.
어플리케이션 서버에서 클라우드 메시징 서비스의 서버로 사용자 등록 정보와 푸쉬 알림 메세지 내용을 전달하기만 하면, 그 이후의 푸시 알림 전송 과정은 클라우드 메시징 서비스가 알아서 처리한 후에 사용자에게 푸시알림을 전달하게 됨
1. 사용자가 웹 앱에 접속하여 알림을 구독할 경우, 클라우드 메시징 서비스로 등록을 요청
2. 요청받은 클라우드 메시징 서비스는 해당 유저의 등록 정보를 제공
3. 유저는 클라우드 메시징 서비스로부터 받은 등록 정보를 애플리케이션 서버로 전송 애플리케이션 서버가 나에게 알림을 보낼 수 있도록 함 (알림 받을 유저 등록 정보)
a. 특정 이벤트로 인해 애플리케이션 서버가 특정 유저에게 푸쉬 알림을 보내야 할 때, 알림을 보낼 대상 유저의 등록 벙보 + 푸쉬 알림의 내용을 클라우드 메시징 서비스로 전달
b. 애플리케이션 서버로부터 수신한 정보를 확인 후, 등록된 유저의 경우 푸시 알림을 보내고 등록되지 않았다면 어플리케이션 서버에 이를 알림
const title = '안녕 내가 누구게?'
const options = {
body: '내가 누구냐면 나도 모르지 히히히히,,,',
icon: '/images/~',
action: 'atom-action
};
registration.showNotification(title, options);
알림 클릭 시 윈도우 창 띄우기
clients.openWindow()
알람 클릭 시 이미 열려있는 창에 집중시키기
// new URL() : url이 products/10 이런식이면 http://products/10 와 같이 바꿔줍니다.
var urlToOpen = new URL(examplePage, self.location.origin).href;
var promiseChain = clients.matchAll({ // matchAll() 은 탭만 반환하고, 웹 워커는 제외합니다.
type: 'window',
includeUncontrolled: true // 현재 서비스워커 이외의 다른 서비스워커가 제어하는 탭들도 포함합니다. 그냥 default로 항상 넣어주세요.
})
.then((windowClients) => {
// windowClients 는 현재 열린 탭들의 값입니다.
var matchingClient = null;
for (var i = 0; i < windowClients.length; i++) {
var windowClient = windowClients[i];
if (windowClient.url === urlToOpen) {
matchingClient = windowClient;
break;
}
}
if (matchingClient) {
return matchingClient.focus();
} else {
return clients.openWindow(urlToOpen);
}
});
// promiseChain은 위 matchingClient.focus()의 실행이 끝난 후 waitUntil()을 수행하기 위한 프로미스 체인입니다.
event.waitUntil(promiseChain);
유저의 권한을 받으면, PushSubscription(PushApi에서 PushManager구독) 이라는 개체를 얻어야 함
PushSubscrption에는 푸쉬 알림을 보낼 주소와 암호화에 필요한 key들이 드어있음
endpoint는 유저 하나에 고유하고, key는 Push Message를 암호화하기 위해 필요
PushSubscription 서버에 저장
웹 푸쉬를 보내기 위해 VAPID keys를 서버가 가지고 있어야 함
Push Message 전송
Push Event 트리거
유저가 알림을 클릭했을 때 어떻게 동작할 지
알림을 보여줌