Передача данных между клиентом и serviceWorker

1

Я хочу попробовать запустить websockets в serviceWorker.

Я пишу код для register 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);
    });
}

И напишите код службыWorker:

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}

Попытка отправить сообщение от службыWorker к клиенту следующим образом:

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

Но event.ports пуст.

В чем дело? Как передавать данные между клиентом и службой Worker.

Теги:
service-worker

2 ответа

1

Чтобы исправить ошибку контроллера, равную нулю, вам нужно добавить активирующий прослушиватель событий

self.clients.claim()

Без этого, когда активист сервисный рабочий, страница не контролируется им до следующей навигации. Это позволяет обслуживающему персоналу взять контроль над страницами, как только он будет активен.

Но я не думаю, что это ваша единственная проблема. Глядя на ваш код, я думаю, вы вводите в заблуждение WebSocket и MessageChannel. Кажется, вы пытаетесь использовать WebSocket для отправки сообщений между клиентом и рабочим сервисом, где вы должны использовать MessageChannel для этого.

Например, если мы хотим отправлять сообщения от клиента в SW и разрешать SW отвечать на эти сообщения, мы создаем MessageChannel, и мы отправляем порт этого канала вместе с сообщением для SW, которое будет использоваться в его ответе. в клиенте:

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]);

в SW:

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");
});
  • 0
    Попробуйте это: developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/… и получите «Эта страница в настоящее время не контролируется работником службы».
  • 0
    Добавление self.clients.claim () и это не помогает
Показать ещё 7 комментариев
0

Правильный и проработанный пример, только для понимания, а не для производства: https://github.com/Shkarbatov/WebSocketInServiceWorkerJS

Ещё вопросы

Сообщество Overcoder
Наверх
Меню