Escolar Documentos
Profissional Documentos
Cultura Documentos
ServiceWorker,MessageChannel,&postMessage
ServiceWorker, MessageChannel,
& postMessage
Last week I wrote an article about a caching strategy for progressive networking that uses
a cache rst and then goes to the networking, sharing messages between web pages and
a ServiceWorker to coordinate updates to cached content. Today Ill describe the inner
workings of the swivel library thats used to simplify message passing for
ServiceWorkers.
Nicols Bevacqua
Asitturnsout,theresmanydifferentwaysinwhichyoucansharemessagesbetweena
ServiceWorker andthewebpagesitcontrols.
https://ponyfoo.com/articles/serviceworkermessagechannelpostmessage
1/8
12/01/2017
ServiceWorker,MessageChannel,&postMessage
worker.postMessage(data);
self.addEventListener('message',functionhandler(event){
console.log(event.data);
});
Assoonasyouhavedifferenttypesofmessagesyouwanttosendtoworkers,thisbecomes
anissue.Youllhavetoturntoaconventionformessagerouting.Acommonconventionisto
defineanenvelopeforyourmessagesthathasa command propertyinit,sonowyoudsend
messageslikethefollowing.
worker.postMessage({command:'deleteCache',key:key});
Thentheworkerneedstobeupdatedwithacommandhandlingrouter,abunchof if willdo
inthesimplercase.Youcanseehowthecodestartsbecomingdilutedwithimplementation
details.
https://ponyfoo.com/articles/serviceworkermessagechannelpostmessage
2/8
12/01/2017
details.
ServiceWorker,MessageChannel,&postMessage
self.addEventListener('message',functionhandler(event){
if(event.data.command==='deleteCache'){
caches.delete(event.data.key);
}
});
varmessageChannel=newMessageChannel();
messageChannel.port1.addEventListener('message',replyHandler);
worker.postMessage(data,[messageChannel.port2]);
functionreplyHandler(event){
console.log(event.data);//thiscomesfromtheServiceWorker
}
self.addEventListener('message',functionhandler(event){
event.ports[0].postMessage(data);//handlethisusingthereplyHandlershowne
});
MessageChannel stuffonthe
3/8
12/01/2017
ServiceWorker,MessageChannel,&postMessage
Thatbeingsaid,havingtotypethisoutsucks.Librarieswilldefinitelyhelpabstractthepain
away,while ServiceWorker cangoonbeingjustaboutthemostpowerfulfeaturethemodern
webhastooffer.
self.clients.matchAll().then(all=>all.map(client=>client.postMessage(data)));
navigator.serviceWorker.addEventListener('message',functionhandler(event)
console.log(event.data);
});
4/8
12/01/2017
ServiceWorker,MessageChannel,&postMessage
workersotherthantheoneyoureexpectingmessagesfrom.
navigator.serviceWorker.addEventListener('message',functionhandler(event)
if(event.source!==worker){
return;
}
console.log(event.data);
});
self.on('fetch',functionhandler(event){
//replytoclienthere
});
self.on('fetch',functionhandler(event){
event.respondWith(caches.match(event.request));
fetch(event.request).then(response=>response.json()).then(function(data)
self.clients.match(event.clientId).then(client=>client.postMessage(data));
});
});
https://ponyfoo.com/articles/serviceworkermessagechannelpostmessage
5/8
12/01/2017
ServiceWorker,MessageChannel,&postMessage
Youcouldstillusethebroadcastingmechanismdiscussedearlier,butitdgotoeveryclientand
notjusttheoriginofthe fetch event.Abetteralternative,fornow,maybetoissueanother
requestfromthepageafterload,maybeaddingacustomheaderindicatingthatweshould
forcea fetch onthe ServiceWorker side.
RonSwansonswivellingtoavoidhumancontact
Swivellinghasanumberofbenefits.TheAPIisunifiedunderaneventemitterstyle.Onthe
client,youcansendmessagestothe ServiceWorker likebelow.
swivel.emit('removecache','v1');
Thenontheworker,youcouldjustlistenforthatwithamatchingAPI.
swivel.on('removecache',(context,key)=>caches.delete(key));
Iftheworkerneedstoreply,itcanuse context.reply .
https://ponyfoo.com/articles/serviceworkermessagechannelpostmessage
6/8
12/01/2017
ServiceWorker,MessageChannel,&postMessage
Iftheworkerneedstoreply,itcanuse context.reply .
swivel.on('removecache',functionhandler(context,key){
caches.delete(key).then(function(){
context.reply('removedcache','ok','whatever');
});
});
Theclientthatsentthemessagethengetstohandlethereplyaslongastheyrelisteningfor
the removedcache event.NotehowtheAPIhereisidenticaltotheAPIforlisteningon
eventsontheServiceWorker.
swivel.on('removedcache',functionhandler(context,success,metadata){
//dosomethingelse
});
swivel.broadcast('announcement',{super:'!important'});
Lastly,aswementionedearlieryoucaninteractwithdifferentServiceWorkerinstances.Instead
ofusingthe swivel.* APIdirectly,youcoulduse swivel.at(worker).* instead.
Messagessentfromaclientusing swivel.at(worker).emit willonlygoto worker ,and
messagesbroadcastedby worker willonlybeavailabletolistenersregisteredusing
swivel.at(worker).on .Thiskindofscopinghelpspreventaccidentswhenphasingoutold
workersandwheninstallingnewones.
https://ponyfoo.com/articles/serviceworkermessagechannelpostmessage
7/8
12/01/2017
ServiceWorker,MessageChannel,&postMessage
YoucancheckoutthefulldocumentationonGitHub.
https://ponyfoo.com/articles/serviceworkermessagechannelpostmessage
8/8