service worker中的client.postMessage()不会调用angularjs控制器中的onmessage处理程序

时间:2017-04-27 21:11:42

标签: javascript angularjs angularfire service-worker

服务工作者消息处理程序:

let angularClient;
self.addEventListener('message', function(event) {
// store the client which sent the message into angularClient variable    
  angularClient = event.ports[0];
 });

服务工作者通知单击处理程序,将数据发送到angularClient

self.addEventListener('notificationclick', function(event) {
event.notification.close();
var url = /localhost:8080|example.com|https:\/\/www.example.com/;
var newurl = "/" + event.notification.data.url;
if (event.notification.data.url) {
  newurl = event.notification.data.url;
}

function endsWith(str, suffix) {
  console.log(str);
  console.log(suffix);
  return str.indexOf(suffix, str.length - suffix.length) !== -1;
}

event.waitUntil(
  clients.matchAll({
    type: 'window'
  })
  .then(function(windowClients) {
    for (var i = 0; i < windowClients.length; i++) {
      var client = windowClients[i];
      if (url.test(client.url) && 'focus' in client) {
        if (endsWith(client.url, newurl)) {
          console.log("URL matched");              
          console.log("sending 1");
          angularClient.postMessage(sendToAngularPayload);
          return client.focus();
        }
        return client.navigate(newurl)
          .then(client => client.focus());
      }
    }
    if (clients.openWindow) {
      console.log("sending 2");
      angularClient.postMessage(sendToAngularPayload); //sendToAngularPayload is defined when notification is received in firebase's messaging.setBackgroundMessageHandler.
      return clients.openWindow('https://www.example.com/#/' + 
   event.notification.data.url);
    }
  })
);

},true);

具有功能

的AngularJs控制器

向服务工作人员发送消息以便存储此客户端的功能

$scope.checkServiceWorker = function() {
    if ('serviceWorker' in navigator) {
        // ensure service worker is ready
        navigator.serviceWorker.ready.then(function(reg) {
            console.log("Send message");
            // PING to service worker, later we will use this ping to 
            //identify our client.
            sendMessage().then(function(event) {
                console.log(event);
            }).catch(function(error) {
                console.log("error", error);
                location.reload();
            });
        }).catch(function() {
            console.log('SW not ready');
            $scope.checkServiceWorker();
        });
    }
}
带有onMessage处理程序的

sendMessage函数

function sendMessage() {
    return new Promise(function(resolve, reject) {
        var messageChannel = new MessageChannel();
        messageChannel.port1.onmessage = function(event) {
            console.log("on message handler", event);
            if (event.data.error) {
                reject(event.data.error);
            } else {
                console.log('inside resolve', event.data);
                console.log("Ping received from SW");
                console.log(event);                    
                resolve(event.data);
            }
        };
        console.log("Sending");
        navigator.serviceWorker.controller.postMessage("ping", 
        [messageChannel.port2]);
        console.log("sent");
    });
}

问题是angularjs控制器内的onMessage Handler会被触发90%的次数,但有时则没有。正如我在开发人员控制台中看到的那样,在打印&#34;发送1&#34;之后,执行在serviceworker.js中停止。在通知单击处理程序中,并且不会在控制器的onMessage处理程序中显示其余日志。

1 个答案:

答案 0 :(得分:0)

worker.ts

self.addEventListener("push", e => {
 const data = e.data.json();
 console.log("Push received");
 console.log("data ", data);
 self.registration.showNotification(data.title, {
   body: "Notified",
 })
 // Broadcasting from a ServiceWorker to every client
 self.clients.matchAll().then(all => all.map(client => client.postMessage(data)));
})

侦听器被添加到navigator.serviceWorker上,而不是特定的 工人

AngularJs控制器:

constructor() {
    navigator.serviceWorker.addEventListener('message', e => console.log(e.data));
}