서비스 워커를 사용하여 알림 관리

Kate Jeffreys
Kate Jeffreys

이 Codelab에서는 서비스 워커를 사용하여 알림을 관리합니다. 이 안내는 서비스 워커와 알림 권한 요청 및 알림 전송의 기본사항에 이미 익숙하다고 가정합니다. 알림에 관해 다시 알아보려면 Notifications API 시작하기 Codelab을 참고하세요. 서비스 워커에 대한 자세한 내용은 맷 건트의 서비스 워커 소개를 참조하세요.

삽입된 Glitch 앱에서는 알림이 자동으로 차단되므로 이 페이지에서 앱을 미리 볼 수 없습니다. 대신 다음 단계를 따르세요.

  1. 수정할 리믹스를 클릭하여 프로젝트를 수정할 수 있도록 합니다.
  2. 사이트를 미리 보려면 앱 보기를 누른 다음 전체 화면 전체 화면을 누릅니다.

Glitch가 새 Chrome 탭에서 열립니다.

이 Codelab을 진행하면서 이 페이지에 삽입된 Glitch의 코드를 변경합니다. 실시간 앱이 있는 새 탭을 새로고침하여 변경사항을 확인합니다.

샘플 앱 및 시작 코드 숙지

먼저 새 Chrome 탭에서 라이브 앱을 살펴보세요.

  1. `Control+Shift+J`(Mac의 경우 `Command+Option+J`)를 눌러 DevTools를 엽니다.
  2. 콘솔 탭을 클릭합니다.

  3. 필터 상자 옆의 수준 드롭다운에서 정보 옵션이 선택되어 있는지 확인합니다.

  4. 실시간 앱의 DevTools 콘솔에 다음과 같은 콘솔 메시지가 표시됩니다.

    TODO: Implement getRegistration().

    이 메시지는 이 Codelab에서 구현할 함수 스텁의 메시지입니다.

이제 이 페이지에 삽입된 Glitch에서 샘플 앱의 코드를 살펴보겠습니다.

  1. 삽입된 Glitch에서 public/index.js를 살펴봅니다.

    • 구현할 함수의 스텁은 registerServiceWorker, getRegistration, unRegisterServiceWorker, sendNotification의 4가지가 있습니다.

    • requestPermission 함수는 알림을 전송할 사용자의 권한을 요청합니다. 알림 API 시작하기 Codelab을 진행했다면 여기에서 requestPermission 함수가 사용된 것을 확인할 수 있습니다. 유일한 차이점은 이제 권한 요청을 해결한 후 사용자 인터페이스도 업데이트된다는 점입니다.

    • updateUI 함수는 앱의 모든 버튼과 메시지를 새로고침합니다.

    • initializePage 함수는 브라우저에서 서비스 워커 기능의 기능 감지를 수행하고 앱 사용자 인터페이스를 업데이트합니다.

    • 스크립트는 페이지가 로드될 때까지 기다린 후 초기화합니다.

  2. 삽입된 Glitch에서 public/service-worker.js를 엽니다.

    이름에서 알 수 있듯이 이 파일을 서비스 워커로 등록하는 코드를 앱에 추가합니다.

    이 파일은 아직 앱에서 사용하지 않지만 서비스 워커가 활성화될 때 콘솔에 메시지를 출력하는 시작 코드가 포함되어 있습니다.

    서비스 워커가 알림을 수신할 때 이를 처리하도록 public/service-worker.js에 코드를 추가합니다.

서비스 워커 등록

이 단계에서는 사용자가 앱 UI에서 Register service worker를 클릭할 때 실행되는 코드를 작성합니다. 이 코드는 public/service-worker.js를 서비스 워커로 등록합니다.

  1. 삽입된 Glitch 편집기에서 public/index.js를 엽니다. registerServiceWorker 함수를 다음 코드로 바꿉니다.

    // Use the Service Worker API to register a service worker.
    async
    function registerServiceWorker() {
      await navigator
    .serviceWorker.register('./service-worker.js')
      updateUI
    ();
    }

    registerServiceWorkerasync function 선언을 사용하여 프로미스를 더 편리하게 처리할 수 있도록 합니다. 이를 통해 Promise의 결정된 값을 await할 수 있습니다. 예를 들어, 위의 함수는 UI를 업데이트하기 전에 서비스 워커 등록 결과를 기다립니다. 자세한 내용은 MDN의 await를 참고하세요.

  2. 사용자가 서비스 워커를 등록할 수 있으므로, 서비스 워커 등록 객체에 대한 참조를 가져올 수 있습니다. public/index.js에서 getRegistration 함수를 다음 코드로 바꿉니다.

    // Get the current service worker registration.
    function getRegistration() {
     
    return navigator.serviceWorker.getRegistration();
    }

    위 함수는 Service Worker API를 사용하여 현재 서비스 워커 등록(있는 경우)을 가져옵니다. 이렇게 하면 서비스 워커 등록 참조를 더 편리하게 가져올 수 있습니다.

  • 서비스 워커 등록 기능을 완료하려면 서비스 워커를 등록 취소하는 코드를 추가합니다. unRegisterServiceWorker 함수를 다음 코드로 바꿉니다.

    // Unregister a service worker, then update the UI.
    async
    function unRegisterServiceWorker() {
     
    // Get a reference to the service worker registration.
      let registration
    = await getRegistration();
     
    // Await the outcome of the unregistration attempt
     
    // so that the UI update is not superceded by a
     
    // returning Promise.
      await registration
    .unregister();
      updateUI
    ();
    }

라이브 앱이 표시 중인 탭에서 페이지를 새로고침합니다. 이제 서비스 워커 등록서비스 워커 등록 취소 버튼이 작동합니다.

서비스 워커에 알림 전송

이 단계에서는 사용자가 앱 UI에서 알림 보내기를 클릭할 때 실행되는 코드를 작성합니다. 이 코드는 알림을 만들고 서비스 워커가 등록되었는지 확인한 다음 postMessage 메서드를 사용하여 알림을 서비스 워커로 전송합니다.

삽입된 Glitch 편집기에서 public/index.js를 열고 sendNotification 함수를 다음 코드로 바꿉니다.

// Create and send a test notification to the service worker.
async
function sendNotification() {
 
// Use a random number as part of the notification data
 
// (so you can tell the notifications apart during testing!)
  let randy
= Math.floor(Math.random() * 100);
  let notification
= {
    title
: 'Test ' + randy,
    options
: { body: 'Test body ' + randy }
 
};
 
// Get a reference to the service worker registration.
  let registration
= await getRegistration();
 
// Check that the service worker registration exists.
 
if (registration) {
   
// Check that a service worker controller exists before
   
// trying to access the postMessage method.
   
if (navigator.serviceWorker.controller) {
      navigator
.serviceWorker.controller.postMessage(notification);
   
} else {
      console
.log('No service worker controller found. Try a soft reload.');
   
}
 
}
}

코드의 역할은 다음과 같습니다.

  • sendNotification는 비동기 함수이므로 await를 사용하여 서비스 워커 등록에 대한 참조를 가져올 수 있습니다.

  • 서비스 워커의 postMessage 메서드는 앱에서 서비스 워커로 데이터를 전송합니다. 자세한 내용은 postMessage에 관한 MDN 문서를 참고하세요.

  • 코드는 postMessage 함수에 액세스하기 전에 navigator.serviceWorker.controller 속성이 있는지 확인합니다. 활성 상태의 서비스 워커가 없거나 페이지가 강제로 새로고침된 경우 (Shift+새로고침) navigator.serviceWorker.controllernull입니다. 자세한 내용은 MDN의 ServiceWorker 컨트롤러 문서를 참고하세요.

서비스 워커에서 알림 처리

이 단계에서는 서비스 워커에 게시된 메시지를 처리하고 사용자에게 알림을 표시하는 코드를 작성합니다.

삽입된 Glitch 편집기에서 public/service-worker.js를 엽니다. 파일 끝에 아래 코드를 추가합니다.

// Show notification when received
self
.addEventListener('message', (event) => {
  let notification
= event.data;
  self
.registration.showNotification(
    notification
.title,
    notification
.options
 
).catch((error) => {
    console
.log(error);
 
});
});

다음은 간단한 설명입니다.

  • self는 서비스 워커 자체를 참조합니다.

  • 이제 서비스 워커가 알림 표시를 처리하지만 기본 앱 UI는 여전히 사용자로부터 알림 권한을 가져와야 합니다. 권한이 부여되지 않으면 showNotification에서 반환된 프로미스가 거부됩니다. 위 코드는 catch 블록을 사용하여 포착되지 않은 Promise 거부 오류를 방지하고 이 오류를 좀 더 적절하게 처리합니다.

문제가 발생하면 glitch.com/edit/#!/codelab-notifications-service-worker-completed에서 완성된 코드를 확인하세요.

이 시리즈의 다음 Codelab인 푸시 알림 서버 빌드로 이동합니다.