Anatomy of Service Worker Communication
Let your App communicate with its Service Worker
I have a SPA that works as a PWA, which means that in the background a service worker makes sure that the required files for the offline mode end up in the cache.
From time to time I also update the Service Worker, which defines which files it should keep offline and which not. Unfortunately, the app itself didn’t get any of this because there was no communication channel for them to talk.
If you research this topic on the web, you have to dig through many architecture pages and documentations that have one thing in common: sometimes they just don’t get to the point. So here are my 50 cents on the subject and my sample implementation.
Preliminary Thoughts
In most examples I’ve read, the authors talk about code for the app itself and code for the Service Worker, but that falls short to me, because in my opinion there are THREE parts:
- The App
- The Service Worker
- The Service Worker Management, which takes care of the proper registration and installation of the service worker
The last part of the code shouldn’t be part of the app itself, in the meaning of SoC (Seperation of Concerns). It does not contribute to the functioning of the app.
The App
Here’s the general anatomy of my App:
1 | var app = { |
Nothing unlikely, as I guess. It is built according to the composite pattern and has one entry point, that is called at the end of the file after it is instantiated.
The Service Worker
The Service Worker lives in its own JS file and its implementation is really straight forward:
1 | var cacheName = 'my-apps-cache-v1.2.3'; |
I won’t go into the depth of my implementation here now, since it doesn’t matter for the message exchange. It is only good for you to know that I have versioned the cache name to exchange it with new versions.
The Service Worker Management
Now the management code for the Service Worker. It has to be loaded with the app code, because it is client code and later on it needs knowledge of the app.
1 | if('serviceWorker' in navigator) { |
Lets Communicate…
In this setup, the communication code can be implemented. Let’s do it as a round trip.
1. Client sends message to Service Worker
As sw-management.js
represents our Service Worker management code, we add a little function to send a message in here:
1 | function sendMessageToServiceWorker(type, msg) { |
We define a type for the purpose of our communcation and a message itself. The function can be called wherever, like this:
1 | sendMessageToServiceWorker("TEST", "Hey, Service Worker"); |
2. Service Worker receives the message
In the Service Worker code we need to add a recipient:
1 | self.addEventListener('message', function(event) { |
3. … and sends a message back to the client
What we want to do with the message depends what we want to achive, but in this example, just let’s greet back:
1 | function sendMessageToClients(type, msg) { |
4. Client receives the answer from the Service Worker
In order to get messages from the Service Worker, we have to implement a receiver in the client also:
1 | if('serviceWorker' in navigator) { |
5. … and shows it in the app
As I pointed out earlier, that the management code has to be loaded alongside with the app code, it’s a breeze to show the message:
1 | var app = { |
1 | if('serviceWorker' in navigator) { |
The Update Message
With this infrastructure, everything is there to show a message, when the Service Worker is updated:
1 | if('serviceWorker' in navigator) { |
Important to point out, that the Service Worker side of the communication is not involved in this case, because only the client-side management code knows when a new version has to be installed.
More Info
- Jake Archibald: The service worker lifecycle
- Demian Renzulli & Andrew Guan: Two-way communication with service workers
- Adam Bar: Handling Service Worker updates – how to keep the app updated and stay sane
- Felix Gerschau: Service Worker Lifecycle Explained
- Felix Gerschau: How to communicate with Service Workers
- Peter Kröner: PostMessage zwischen Service Worker und Client(s) (GERMAN)
You can interact with this article (applause, criticism, whatever) by mention it in one of your posts or by replying to its syndication on Mastodon, which will be shown here as a Webmention ... or you leave a good old comment with your GitHub account.
In case your blog software can't send Webmentions, you can use this form:
Webmentions
No Webmentions yet...
Comments