ServiceWorker 中 SharedWorker 端口的等价物?

Equivalent of SharedWorker Port in ServiceWorker?

SharedWorker 使用消息端口与 ParentWorker 交换消息。

ParentWorker

var port = new SharedWorker('/worker.js').port;
port.onmessage = function(e){
    console.log(e.data);
};
port.start();
port.postMessage("Hello Shared Worker. I'm Mr. Tab");

SharedWorker (worker.js)

onconnect = function(e){
    var port = e.ports[0];
    port.onmessage = function(e){
        console.log(e.data);
    };
    port.start();
    port.postMessage("Hello Mr. Tab. I'm Shared Worker.");
};

Service Worker 呢?有没有类似SharedWorker端口的东西?

通过检查 ServiceWorker.prototype,您似乎可以使用 myWorker.postMessage 方法,但似乎没有 window 端的 myWorker.onmessage 事件。另请参阅 https://slightlyoff.github.io/ServiceWorker/spec/service_worker/ 记录了这一点。

您可以使用 self.onmessage 事件(http://www.w3.org/TR/service-workers/#service-worker-global-scopehttps://slightlyoff.github.io/ServiceWorker/spec/service_worker/) 但似乎没有 self.postMessage 工人方面的方法。

所以目前看来你可以向Service Worker发送消息,但是你不能反过来。考虑到 ServiceWorkerGlobalScope 继承自 http://www.w3.org/TR/service-workers/ 中的 WorkerGlobalScope 你应该可以,但事实并非如此我发现的文件中明确提到。考虑到 https://slightlyoff.github.io/ServiceWorker/spec/service_worker/ 的文档,它现在继承自 EventTarget 而不是至少在 Chrome 浏览器中。

作为一个建议,也许反向通信可以通过发送轮询网络请求来笨拙地实现,服务工作者将以特殊方式作为缓存命中。

这是它的行为方式:

// in the page:
navigator.serviceWorker.controller.postMessage("Hi!");

// in the ServiceWorker:
self.onmessage = function(event) {
  event.source; // instance of Client
  event.data; // "Hi!"
  // reply
  event.source.postMessage("Hey!");
};

// back in the page:
navigator.serviceWorker.onmessage = function(event) {
  event.source; // instance of ServiceWorker
  event.data; // "Hey!"
};

在撰写本文时,Chrome 目前根据较早的规范将邮寄消息从 ServiceWorker 发送到 Window 到 window.onmessage。此外,event.source 为空。

如果您同时需要解决方案,请传入您自己的MessageChannel。在 https://jakearchibald.github.io/isserviceworkerready/demos/postMessage/

查看演示

@Jaffa The Cake 的答案只是一个简单的进出消息通道,而不是 SharedWorker 端口的完全等价物。此时,没有内置类似于ServiceWorker中的SharedWorker端口的接口。消息通道API是必需的。这是一个。

yourapp.js

var mc = new MessageChannel();
mc.port1.onmessage = function(e){
    console.log(e.data);
};
var sw = navigator.serviceWorker;
sw.register('/sw.js',{scope : '/'}).then(function(){
    console.log("Service Worker is successfully registered.");
}).catch(function(er){
    console.log("Registration failed.");
});
sw.ready.then(function(reg){
    reg.active.postMessage('',[mc.port2]); //initialise the messaging channel
    mc.port1.postMessage("Hello Service Worker. I'm Mr. Tab.");
});

sw.js

//equals to onconnect in Shared Worker
onmessage = function(e){
    var port = e.ports[0];
    port.onmessage = function(e){
        console.log(e.data);
    };
    port.postMessage("Hello Mr. Tab. I'm Service Worker.");
};

注意:此代码已在 Chrome 43 Beta 上测试。