首页 > 解决方案 > 客户端页面和服务工作者之间的双向通信

问题描述

拥有一个由 preact-cli 生成的 preact 应用程序(使用工作箱),我的目标是在 service worker 上注册一个“消息”事件处理程序,从应用程序发布消息并最终收到回复。

就像是:

/* app.js */
navigator.serviceWorker.postMessage('marco');

const response = ? // get the response somehow
/* sw.js */
addEventListener('message', function (e) { return 'polo' });

我对服务人员没有太多经验,并且有很多移动部件让我感到困惑,比如工作箱对服务人员施展魔法,预先隐藏了注册服务人员的代码,而服务人员通常难以调试。

到目前为止,我已经按照 preact-cli 文档的说明sw.js在目录中放置了一个文件: https ://preactjs.com/cli/service-worker/src/

我知道我应该附加一个事件侦听器,但我找不到有关执行此操作的对象的文档。

标签: javascriptservice-workerworkboxpreact

解决方案


(Workbox 和 Preact 都与这个问题没有太大关系。Workbox 允许您在 Service Worker 中使用您喜欢的任何其他代码,Preact 也应该用于您的客户端应用程序。)

此示例页面演示了从客户端页面向服务工作者发送消息,然后使用MessageChannel. 客户端页面上使用的相关帮助代码如下所示:

function sendMessage(message) {
  return new Promise(function(resolve, reject) {
    const messageChannel = new MessageChannel();
    messageChannel.port1.onmessage = function(event) {
      // The response from the service worker is in event.data
      if (event.data.error) {
        reject(event.data.error);
      } else {
        resolve(event.data);
      }
    };

    navigator.serviceWorker.controller.postMessage(message,
      [messageChannel.port2]);
  });
}

然后在您的服务人员中,您使用MessageChannel' 端口进行响应:

self.addEventListener('message', function(event) {
  // Your code here.

  event.ports[0].postMessage({
    error: // Set error if you want to indicate a failure.
    message: // This will show up as event.data.message.
  });
});

您也可以使用Comlink 库来简化逻辑。


推荐阅读