3

我有一个问题,我MessageChannel没有从服务人员向客户发送消息。为什么 MessageChannel 永远阻塞而客户端永远不会收到消息?

在 sw onfetch事件中我创建了一个MessageChannel然后我做postMessage,但是客户端永远不会被addEventListener('message'解雇,为什么?

对于服务人员,我创建了这样的方法:

self.addEventListener("fetch", async (event) => {
  // Exit early if we don't have access to the client.
  // Eg, if it's cross-origin.
  if (!event.clientId) return null;

  // eslint-disable-next-line
  const client = await clients.get(event.clientId);
  const response = await sendMessageToClient(client, { url: event.request.url }, 5000);
})

async function sendMessageToClient(client, message, timeoutAfter) {
  // Exit early if we don't get the client.
  // Eg, if it closed.
  if (!client) return null;

  // 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.
  return await new Promise((resolve, reject) => {
    const messageChannel = new MessageChannel();
    messageChannel.port1.onmessage = function (event) {
      if (event.data && event.data.error) {
        reject(event.data.error);
      } else {
        resolve(event.data);
      }
    };

    // This sends the message data as well as transferring messageChannel.port2 to the client.
    // The client 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
    client.postMessage(message, [messageChannel.port2]);

    // Set up the timeout
    setTimeout(() => {
      messageChannel.port1.close();
      messageChannel.port2.close();

      reject('Promise timed out after ' + timeoutAfter + ' ms');

    }, timeoutAfter);
  });
}

在客户端上,我希望在这里收到消息:

// Set up a listener for messages posted from the service worker.
// The service worker is set to post a message to specific client only
// so you should see this message event fire once.
// You can force it to fire again by visiting this page in an Incognito window.
navigator.serviceWorker.addEventListener('message', function (event) {
  console.log(event.data);
});

但我从来没有在客户端收到消息,如果没有超时,它将永远保持 w8。

更新

我试过的:

  window.addEventListener('message', function (event) { console.log('window.addEventListener', event.data) });
  window.onmessage = function (event) { console.log('window.onmessage', event.data) };
  navigator.serviceWorker.addEventListener('message', function (event) { console.log('navigator.serviceWorker.addEventListener', event.data) });
  navigator.serviceWorker.onmessage = function (event) { console.log('navigator.serviceWorker.onmessage', event.data) };
  // navigator.serviceWorker.controller.addEventListener('message', function (event) { console.log('navigator.serviceWorker.contoller.addEventListener', event.data) });
  // navigator.serviceWorker.controller.onmessage = function (event) { console.log('navigator.serviceWorker.contoller.onmessage', event.data) };
  navigator.serviceWorker.ready.then(function (registration) {
    console.log('navigator.serviceWorker.ready');
    registration.active.addEventListener('message', function (event) { console.log('registration.active.addEventListener', event.data) });
    registration.active.onmessage = function (event) { console.log('registration.active.onmessage', event.data) };
  });

  navigator.serviceWorker.register("sw.js")
    .then(function (registration) {
      // Registration was successful
      console.log("ServiceWorker registration successful with scope: ", registration.scope);
    })
    .catch(function (error) {
      console.error("Service Worker Error", error);
    });
}

我得到的唯一日志是:

导航到http://localhost:3000/ navigator.serviceWorker.ready

ServiceWorker 注册成功,范围:

http://localhost:3000/

4

0 回答 0