首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >铬ServiceWorker postMessage

铬ServiceWorker postMessage
EN

Stack Overflow用户
提问于 2015-05-11 21:15:03
回答 4查看 20.8K关注 0票数 11

我尝试在web应用程序和相应的服务工作者之间进行postMessage。到目前为止,该服务人员已成功注册和工作。不幸的是,我注意到了一些奇怪的行为:

  1. navigator.serviceWorker.controller总是null
  2. 在服务工作者端,我按照以下方式实现了postMessage
代码语言:javascript
复制
self.addEventListener('message', function (evt) {
    console.log('postMessage received', evt);
});

不幸的是,要回发到原点evt.origin=''evt.source=null的重要字段不包含所需的值。尽管如此,我总是收到发送的evt.data

你知道怎么回发吗?

非常感谢!

Andi

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-05-13 22:15:17

将工作人员的响应发送回受控应用程序的一种方法是在这个演示中显示,并按以下方式完成(我还没有实际测试过这一点,但演示运行得很好,代码似乎与规范一致)。

在主页中:

代码语言:javascript
复制
function sendMessage(message) {
  // This wraps the message posting/response in a promise, which will
  // resolve if the response doesn't contain an error, and reject with
  // the error if it does. If you'd prefer, it's possible to call
  // controller.postMessage() and set up the onmessage handler
  // independently of a promise, but this is a convenient wrapper.
  return new Promise(function(resolve, reject) {
    var messageChannel = new MessageChannel();
    messageChannel.port1.onmessage = function(event) {
      if (event.data.error) {
        reject(event.data.error);
      } else {
        resolve(event.data);
      }
    };
    // This sends the message data as well as transferring
    // messageChannel.port2 to the service worker.
    // The service worker can then use the transferred port to reply
    // via postMessage(), which will in turn trigger the onmessage
    // handler on messageChannel.port1.
    // See
    // https://html.spec.whatwg.org/multipage/workers.html#dom-worker-postmessage
    navigator.serviceWorker.controller.postMessage(message, [messageChannel.port2]);
  });
}

在服务工作者代码中:

代码语言:javascript
复制
self.addEventListener('message', function(event) {
  event.ports[0].postMessage({'test': 'This is my response.'});
});

然后,您应该能够使用sendMessage函数返回的承诺来对来自服务工作者的响应执行您想要的操作。

票数 19
EN

Stack Overflow用户

发布于 2017-03-22 23:29:49

@GalBracha问你是否可以在不首先发送信息的情况下与客户沟通--是的!下面是一个快速示例,说明当收到推送通知时(不是当用户单击通知时,而是当服务工作人员收到事件时),当我想向客户发送消息时,我是如何做到的:

在您的客户js中(服务人员注册后,等等):

代码语言:javascript
复制
// navigator.serviceWorker.addEventListener('message', ... ) should work too
navigator.serviceWorker.onmessage = function (e) {
    // messages from service worker.
    console.log('e.data', e.data);
};

在服务工作人员中,为了响应某些事件(可能是安装事件):

代码语言:javascript
复制
// find the client(s) you want to send messages to:
self.clients.matchAll(/* search options */).then( (clients) => {
    if (clients && clients.length) {
        // you need to decide which clients you want to send the message to..
        const client = clients[0];
        client.postMessage("your message");
    }

诀窍是(显然?)若要将消息事件的侦听器附加到serviceWorker对象,而不是window对象,请执行以下操作。

票数 11
EN

Stack Overflow用户

发布于 2021-03-24 16:26:02

广播频道API更容易

与使用广播频道API相比,在服务工作者与其客户端之间来回发送信息要容易得多。

以下是广播的工作原理

在服务工作者和客户端中定义一个新的广播频道。

代码语言:javascript
复制
const channel4Broadcast = new BroadcastChannel('channel4');

若要在工作人员或客户端中发送广播消息,请执行以下操作:

代码语言:javascript
复制
channel4Broadcast.postMessage({key: value});

若要接收,请在工作人员或客户端中发送广播消息:

代码语言:javascript
复制
channel4Broadcast.onmessage = (event) => {
    value = event.data.key;
}

广播还允许在客户端、客户端和服务工作者的网络工作者之间发送消息。

警告

然而,这种简单是要付出代价的。按照目前的情况,服务人员不会醒来接收广播消息。因此,只有当服务工作者处于运行(活动或等待)状态时,即当客户端可见时,它才能工作。尽管如此,这仍然可能是有用的,例如,广播版本号或网络推送等。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30177782

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档