Javascript 未在多个选项卡中调用service worker的推送事件

Javascript 未在多个选项卡中调用service worker的推送事件,javascript,google-chrome,push-notification,service-worker,web-push,Javascript,Google Chrome,Push Notification,Service Worker,Web Push,我正在使用Web推送协议发送推送通知。我已注册了一名服务人员,并已在一个选项卡中成功订阅pushManager。当我发送消息时,push事件能够接收通知并将消息记录在控制台中 我正在打开相同的url,同一个服务人员正在注册,并使用下面的代码段返回相同的订阅 serviceWorkerRegistration.pushManager.getSubscription() 但当我发送消息时,第一个选项卡只在控制台中记录消息。第二个选项卡不在控制台中记录消息 当我关闭第一个选项卡并发送消息时,现在我可以

我正在使用Web推送协议发送推送通知。我已注册了一名服务人员,并已在一个选项卡中成功订阅pushManager。当我发送消息时,push事件能够接收通知并将消息记录在控制台中

我正在打开相同的url,同一个服务人员正在注册,并使用下面的代码段返回相同的订阅

serviceWorkerRegistration.pushManager.getSubscription()

但当我发送消息时,第一个选项卡只在控制台中记录消息。第二个选项卡不在控制台中记录消息

当我关闭第一个选项卡并发送消息时,现在我可以在第二个选项卡控制台中看到由服务人员记录的消息

    clients.matchAll({
        type: 'window',
        includeUncontrolled: true
      })
      .then(function(windowClients)
      {   
        windowClients.forEach(function(windowClient){
        windowClient.postMessage({
          message: 'Received a push message.'+event.data.text(),
          time: new Date().toString()
        });
      });

});
注意:两个选项卡加载在同一原点。 示例:
https://localhost:8080/WebPush

下面是我的服务人员代码

    self.addEventListener('push', function(event) {
      if (event.data) {
         console.log('This push event has data: ', event.data.text());
      } 
      else {
         console.log('This push event has no data.');
      }
   });
同时,当我尝试使用firebase时,我可以在两个选项卡中接收消息

有人能帮我用网络推送在两个标签上接收信息吗


提前感谢。

服务人员将对推送事件做出一次响应。这将在推送通知生成的线程中发生。它不会为每个浏览器选项卡启动。事实上,它将是或应该是服务工作者的一个独立实例,与任何客户端正在使用的实例不同。推送通知的客户端是操作系统,如果您愿意的话,有点像无头客户端

是,您将看到控制台消息被记录。我怀疑Chrome的内部有这样一个线程:寻找第一个带有控制台的开放客户端来传递这些消息

对于Chrome、FireFox、Opera、Samsung或Edge采用的实际线程模型,我无法解释不同的事件响应是如何线程化的,但在获取、推送和后台同步方面,它们本质上应该是分开的


我希望这有助于您了解这个概念,但您看到的是我希望看到的,一个控制台记录来自推送启动的软件线程的消息。

我找到了实现此用例的一种可能方法

触发推送事件后,使用服务工作者客户端API,我将找出同一来源中打开的客户端的数量,并向所有客户端发布消息

下面是需要在service worker中添加内部推送事件的代码段

    clients.matchAll({
        type: 'window',
        includeUncontrolled: true
      })
      .then(function(windowClients)
      {   
        windowClients.forEach(function(windowClient){
        windowClient.postMessage({
          message: 'Received a push message.'+event.data.text(),
          time: new Date().toString()
        });
      });

});
并添加一个服务工作者侦听器

    navigator.serviceWorker.addEventListener('message', function(event) {
      console.log('Received a message from service worker: ', event.data);
    });

这将有助于在多个选项卡中接收推送消息。

感谢您的及时回复。我知道服务器工作者在单独的线程上运行,并将消息传递给第一个打开的客户端。但是firebase是如何做到这一点的呢。因为firebase还使用服务人员发送推送通知。我想应该有办法实现我的用例。仅供参考,我对使用FireBase一无所知。但这不是在服务器/云端吗?因此,它将与客户端设备分离。推送通知将基于注册的客户端(设备)进行。只有一条推送消息会发送到注册的设备。不是每个打开的选项卡都有一个。消息toast(除非您发送的消息完全在后台使用)将出现在任何浏览器的上方,即使浏览器未打开。