服务人员与客户沟通

时间:2017-02-09 02:22:10

标签: client service-worker

我一直试图从服务工作者向客户发送消息但是如果我使用

self.clients.matchAll()
.then((clients) => {
  clients.forEach(function(client) {
    client.postMessage({msg: 'Hello from SW'})
  })
})
即使我在浏览器中打开了标签,但是如果我从客户端服务工作者发送消息,它也不会发送给任何客户端>

// client
navigator.serviceWorker.controller.postMessage({title: 'Send message from client'})

和服务工作者

self.addEventListener('message', function(event) {
  self.clients.fetchAll()
    .then((clients) => {
      clients.forEach(function(client) {
        client.postMessage({msg: 'Hello from SW'})
     })
  })
})

它可以发送消息并查找客户端。 我做错了什么?,我应该使用indexedDB吗?

2 个答案:

答案 0 :(得分:12)

我不相信clients.fetchAll()存在。您可能意味着clients.matchAll(),它应该为您提供您描述的行为:

self.clients.matchAll().then(clients => {
  clients.forEach(client => client.postMessage({msg: 'Hello from SW'}));
})

允许服务工作者与客户端通信,同时避免必须逐个发送消息的更好的替代方案是make use of the Broadcast Channel API。现在,Chrome和Firefox的最新版本都支持它。

// From service-worker.js:
const channel = new BroadcastChannel('sw-messages');
channel.postMessage({title: 'Hello from SW'});

// From your client pages:
const channel = new BroadcastChannel('sw-messages');
channel.addEventListener('message', event => {
  console.log('Received', event.data);
});

答案 1 :(得分:0)

添加includeUncontrolled选项应该可以:

for (const client of await clients.matchAll({includeUncontrolled: true, type: 'window'})) {
  client.postMessage(message);
}