简体   繁体   English

服务工作者中的 client.postMessage() 不会在 angularjs 控制器内调用 onmessage 处理程序

[英]client.postMessage() in service worker does not call onmessage handler inside angularjs controller

Service Worker Message Handler:服务工作者消息处理程序:

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

Service Worker Notification Click Handler, Which sends data to angularClient Service Worker Notification Click Handler,它向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 Controller with functions带函数的 AngularJs 控制器

Function to send message to service worker so that it stores this client向 Service Worker 发送消息以便它存储此客户端的功能

$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();
        });
    }
}

sendMessage function with onMessage handler带有 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");
    });
}

The problem is that onMessage Handler inside angularjs controller gets fired 90% of the times, but sometimes it does not.问题是 angularjs 控制器中的 onMessage Handler 被触发了 90% 的时间,但有时不会。 As I can see in the developer console, the execution stops in serviceworker.js after I print "sending 1" in the notification click handler, and does not show rest of the logs inside the controller's onMessage handler.正如我在开发人员控制台中看到的那样,在通知单击处理程序中打印“发送 1”后,serviceworker.js 中的执行停止,并且不会在控制器的 onMessage 处理程序中显示其余日志。

worker.ts工人.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)));
})

The listener is added on navigator.serviceWorker and not on a specific worker侦听器添加到 navigator.serviceWorker 而不是特定的 worker

AngularJs controller: AngularJs 控制器:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM