New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
An example using Service Worker? #27
Comments
You are right, a ServiceWorker doesn’t have It’s probably a good idea for me to write an example for this. Hope this helps. |
I am curious, tho. What is your current use-case with Comlink + ServiceWorker? What are you exposing? |
I'm using Notification APIs that are only available in a SW (as far as I know), as well as checking progress of caching events. I know it's not a core use of Comlink but I've found it useful so far! |
You can use Notification API without SW :) Progress of caching is definitely an interesting use case. |
AFAIK you can show a notification, but can't for example call getNotifications(): https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration/getNotifications Would love to be wrong though :) |
That’s correct. I thought you just wanted to show notifications |
+1 for a canonical, best-practice example of establishing an RPC connection with a ServiceWorker. |
I'm trying to follow the recommendation in #27 (comment):
While the class RunInSW {
// ...
}
self.addEventListener('message', async (event) => {
if (event.data === 'init-comlink') {
const clients = await self.clients.matchAll();
for (const client of clients) {
Comlink.expose(RunInSW, client);
}
}
}); leads to Error: endpoint does not have all of addEventListener, removeEventListener and postMessage defined |
Here's what I've come up with so far, which seems to work: In the function initComlink() {
const channel = new MessageChannel();
navigator.serviceWorker.controller.postMessage(channel.port2, [channel.port2]);
window._runInSW = Comlink.proxy(channel.port1);
channel.port1.start();
}
if (navigator.serviceWorker.controller) {
initComlink();
}
navigator.serviceWorker.addEventListener('controllerchange', initComlink); In the SW context: self.addEventListener('message', (event) => {
if (event.data instanceof MessagePort) {
Comlink.expose(api, event.data);
event.data.start();
}
}); |
I think I like your solution better. I’ll adjust my PR :) |
When I saw this I assumed I could slot a service worker in the same place a web worker was being used in the example, but service workers don't have
self.postMessage
, so it doesn't work. I've got it working now by hooking up the proxy through a MessagePort in a message event - is that the best way to do it?Either way, it would be great to have an example showing the best practise for this.
The text was updated successfully, but these errors were encountered: