简体   繁体   中英

Trigger a Client function with a service worker

I have a chat platform I'm building for fun. I have built notifications into the platform. On a browser it looks like this when you click the notification, with noticeSource being the user the new message is from. So it knows, to focus the page and then use the loadChat() function to load the chat associated with that user.

note.onclick=function(){
                        parent.focus();
                        console.log(this);
                        loadChat(noticeSource,el);
                        this.close()
                    };

However, I am also running this as PWA for android, so when it detects its on a phone it uses the Service worker showNotification method. I use this function to detect the click and to bring the app into focus.

self.addEventListener('notificationclick', function (event)
{
    console.log("EVENT!",event.notification.data);
    var target=event.notification.data;
    const rootUrl = new URL('./index.php', location).href;
    event.notification.close();
    event.waitUntil(
        clients.matchAll().then(matchedClients => {
            for (let client of matchedClients){
                console.log(client.url,rootUrl);
                if (client.url.indexOf(rootUrl) >= 0){
                    console.log("Focus1");
                    return client.focus();
                }
            }
            return clients.openWindow(rootUrl).then(
                function (client) {
                    console.log("Focus2");
                    client.focus();
                }
            );
        })
    );
});

What I can't figure out is how to communicate between the SW and the client that the client should run the loadChat() function and pass along the user it should run it for. In general if someone could point me toward a resource that explains how to communicate between the SW and the client that would be appreciated. I've looked but haven't found anything and I am assuming it's because I'm not really clear on how service workers are suppose to work.

As is often the case, I found an answer after I posted the question. The client object has a method postMessage() , so once I have my client found I can use that to post a message with the userName, on the client side I can use eventListener navigator.serviceWorker.onmessage to catch messages from the sw and execute functions.

self.addEventListener('notificationclick', function (event)
{
    console.log("EVENT!",event.notification.data);
    var target=event.notification.data;
    const rootUrl = new URL('./index.php', location).href;
    event.notification.close();
    console.log(clients);
    event.waitUntil(
        clients.matchAll().then(matchedClients => {
            for (let client of matchedClients){
                console.log(client.url,rootUrl);
                if (client.url.indexOf(rootUrl) >= 0){
                    console.log(client);
                    client.focus();
                    client.postMessage(event.notification.data);
                    return ;
                }
            }
            return clients.openWindow(rootUrl).then(
                function (client) {
                    console.log("Focus2");
                    client.focus();
                }
            );
        })
    );
});

and on the client side

sw=navigator.serviceWorker;
sw.register('sw.js').then(function(registration){console.log("Scope:",registration.scope)});

sw.onmessage=function(event){
    loadChat(event.data,document.getElementById(event.data));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM