在client和serviceWorker之间传输数据

2024-04-05

我想尝试在 serviceWorker 中运行 websockets。

我编写了注册serviceWorker的代码:

if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register(
            GetDataForUser.settings.service_worker + "?version=" + GetDataForUser.settings.service_worker_version,
            {scope: './'}
        )
        .then(() => navigator.serviceWorker
            .ready
            .then((worker) => {
        console.log(worker);
                worker.sync.register('syncdata');
            })
        )
        .catch((err) => console.log(err));
    navigator.serviceWorker.addEventListener('message', event => {
        console.log('++++++++++++++++++++', event.data.msg, event.data.url);
    });
}

并编写serviceWorker代码:

var ws = null;

self.addEventListener('install', (event) => {
    console.log('Install');
});

self.addEventListener('activate', (event) => {
    console.log('Activate');

    ws = new WebSocket('ws://local.ll:8880');

    ws.onopen = function() {
        console.log("Open");
    };

    // On message receive
    ws.onmessage = function (event) {
        console.log("Message receive " + event.data);
        console.log(event);
        event.ports[0].postMessage({'test': 'This is my response.'});
    };

    // On error connection
    ws.onerror = function (error) {
        console.log("Error " + error.message);
    };

    // On close connection
    ws.onclose = function (event) {
        if (event.wasClean) {
            console.log('clean closed');

        } else {
            console.log('broken connection');
        }
        console.log('Code: ' + event.code + ' reason: ' + event.reason);
    };
});

self.addEventListener('fetch', (event) => {});

self.addEventListener('message', function (evt) {
    console.log('postMessage received', evt.data);
    ws.send('121212');
});

接下来我尝试将数据发送到 serviceWorker:

navigator.serviceWorker.controller.postMessage({'hello': 'world'});

但收到错误:

Uncaught TypeError: Cannot read property 'postMessage' of null

console.log(navigator.serviceWorker);
ServiceWorkerContainer {controller: null, ready: Promise, oncontrollerchange: null, onmessage: null}

接下来尝试从 serviceWorker 向客户端发送消息:

event.ports[0].postMessage({'test': 'This is my response.'});

但 event.ports 是空的。

怎么了? 如何在client和serviceWorker之间传输数据。


要修复控制器为空的错误,您需要添加激活事件侦听器

self.clients.claim()

如果没有这个,当服务工作者被激活时,页面不会被它控制,直到下一次导航。这允许服务工作人员在页面处于活动状态时立即控制页面。

但我不认为这是你唯一的问题。看看你的代码,我认为你混淆了 WebSocket 和 MessageChannel。您似乎尝试使用 WebSocket 在客户端和服务工作人员之间发送消息,而您应该使用 MessageChannel 来发送消息。

例如,如果我们想要从客户端向软件发送消息并允许软件响应这些消息,我们创建一个 MessageChannel,然后将该通道的端口与消息一起发送,以供软件在其响应中使用。 在客户端:

var msg = new MessageChannel();
msg.port1.onmessage = function(event){
    //Response received from SW
    console.log(event.data);
};
// Send message to SW
navigator.serviceWorker.controller.postMessage("hello", [msg_chan.port2]);

在软件中:

self.addEventListener('message', function(event){
    //Message received from client
    console.log(event.data);
    //Send response to client using the port that was sent with the message
    event.ports[0].postMessage("world");
});
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在client和serviceWorker之间传输数据 的相关文章

随机推荐