Где разместить EventListeners для сервисной работы - PullRequest
0 голосов
/ 18 января 2019

В основном я пытаюсь выполнить, чтобы показать диалоговое окно, когда обнаружена новая версия сервисной программы, а затем чтобы пользователь решил перезагрузить ее, чтобы получить ее.Для этого нам нужно активно установить skipWaiting перед перезагрузкой окна.

Вот мое действие:

  onClickHandler = () => {
    console.log('on click', 'posting skipWaiting');
    navigator.serviceWorker.controller.postMessage('skipWaiting');
  };

Вот моя попытка создать eventListener:

navigator.serviceWorker
    .register(swUrl)
    .then(registration => {
      registration.onupdatefound = () => {
        const installingWorker = registration.installing;
        if (installingWorker == null) {
          return;
        }
        installingWorker.onstatechange = () => {
          console.log('worker state', installingWorker.state);
          if (installingWorker.state === 'installed') {
            if (navigator.serviceWorker.controller) {
              console.log(
                'New content is available and will be used when all ' +
                  'tabs for this page are closed.'
              );

              navigator.serviceWorker.addEventListener('message', event => {
                console.log('skip waiting');
                if (event.data === 'skipWaiting') {
                  self.skipWaiting();
                }
              });
            }
          }
        };
      };
    })
    .catch(error => {
      console.error('Error during service worker registration:', error);
    });

Проблема в том, что navigator.serviceWorker.addEventListener('message', event => не запускается.Я неправильно объявляю слушателя?

Ответы [ 2 ]

0 голосов
/ 26 января 2019

Проблема в том, что предоставленный вами код определяет только получение и отправку сообщений от вашего клиента сервисному работнику.

Приведенный ниже метод определил сообщение для отправки вашему контроллеру (активному) работнику службы.

onClickHandler = () => {
    console.log('on click', 'posting skipWaiting');
    navigator.serviceWorker.controller.postMessage('skipWaiting');
};

В приведенном ниже определении добавлен прослушиватель событий в ваш контейнер ServiceWorker для получения любых сообщений, отправленных работником службы.

navigator.serviceWorker.addEventListener('message', event => {
    console.log('skip waiting');
    if (event.data === 'skipWaiting') {
        self.skipWaiting();
    }
});

Теперь вам нужно определить обработчики событий из файла рабочего сервиса для получения и отправки сообщений.

В файле рабочего сервиса для получения сообщений от клиента:

self.addEventListener('message', function handler (event) {
   console.log('skip waiting');
   if (event.data === 'skipWaiting') {
      self.skipWaiting();
   }
});

Чтобы отправить сообщения от serviceworker вашему клиенту:

self.addEventListener('fetch', function(event) {
  self.clients.matchAll().then(all => all.map(client => client.postMessage('data from webworker')));
});

Вы также можете отправить данные обратно из сервисного центра, используя MessageChannel. На вашем клиенте вы должны определить что-то вроде ниже:

    navigator.serviceWorker
        .register(swUrl)
        .then(registration => {
            var messageChannel = new MessageChannel();
            // listener for messages from the ServiceWorker    
            messageChannel.port1.addEventListener('message', (event) => console.log(event.data)); 

            function sendMessage (message) {
                //send message to the active service worker
                navigator.serviceWorker.controller.postMessage(message, [messageChannel.port2]);
            }
      onClickHandler = () => {
          sendMessage('skipWaiting');
      };
   });

Мне показалось, что приведенная ниже статья весьма полезна.

ServiceWorker, MessageChannel и postMessage от Николас Беваква

0 голосов
/ 21 января 2019

Вы рядом. В установленном вами блоке вы можете проверить

navigator.serviceWorker.controller

Если это существует, это означает, что старый контент будет удален, а новый контент будет добавлен в кеш. Это идеальное время для отображения сообщения или принудительного обновления.

  navigator.serviceWorker.register('service-worker.js').then(function (registration) {

                    $log.debug('The service worker has been registered ', registration);

                    if(navigator.online) {
                        toastr.warning('Offline Mode', 'Application Status');
                    }

                    // updatefound is fired if service-worker.js changes.
                    registration.onupdatefound = function () {
                        // The updatefound event implies that reg.installing is set; see
                        // https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html#service-worker-container-updatefound-event
                        var installingWorker = registration.installing;

                        installingWorker.onstatechange = function () {
                            switch (installingWorker.state) {
                                case 'installed':
                                    if (navigator.serviceWorker.controller) {
                                        // At this point, the old content will have been purged and the fresh content will
                                        // have been added to the cache.
                                        // It's the perfect time to display a "New content is available; please refresh."
                                        // message in the page's interface.
                                        toastr.info('Application has been updated, please refresh this page for the most recent version');

                                        window.location.reload();

                                        });
                                        caches.delete('scope-dynamic').then(function () {
                                            $log.debug('Killed the dynamic cache!');
                                        })
                                        $log.debug('New or updated content is available.');
                                    } else {
                                        // At this point, everything has been precached.
                                        // It's the perfect time to display a "Content is cached for offline use." message.
                                        toastr.success('Content is cached for offline use.', 'Application Status');
                                        $log.debug('Content is now available offline!');
                                    }
                                    break;

                                case 'redundant':
                                    $log.error('The installing service worker became redundant.');
                                    break;

                            }
                        };
                    };
                }).catch(function (e) {
                    $log.error('Error during service worker registration:', e);
                });

Там есть несколько угловатых вещей, но это должно помочь вам добраться туда, где вы хотите быть.

...