preface

The capability of the serviceWorker determines what it needs to do. Part of the logic processing of the site page is transferred to the serviceWorker layer, where the page layer interacts with the serviceWorker layer to achieve message communication.

Here is the message communication between the two environments.


The window communicates to the serviceWorker

This is an example of how the window layer communicates with the serviceWorker layer.

1. ServiceWorker.postMessage

The page layer communicates with the ServiceWorker environment through postMessage of the ServiceWorker interface.

Obtaining the ServiceWorker interface:

The ServiceWorker interface can be obtained in two ways

  • navigator.serviceWorker.controller“Is often used in this way.
  • navigator.serviceWorker.ready.then(swReg => swReg[state]): the state of{installing, waiting, active}

When postMessage is sent, the serviceWorker environment uses the onMessage event to process it.

Send a message:

Message sending implementation:

index.html

// page window environment

if(navigator.serviceWorker.controller) { // Need to check whether controlled
	navigator.serviceWorker.controller.postMessage('message');  // The first argument to postMessage can be any value or JavaScript object processed by a structured clone algorithm, including a circular reference.
}
Copy the code

sw.js

/ / serviceWorker environment

self.addEventListener("message", e => {
  console.log("message", e);
  // Retrieve postMessage data from e.data
})
Copy the code

Receiving messages:

The ServiceWorkerContainer interface is used to listen on onMessage.

navigator.serviceWorker.onmessage
Copy the code

The serviceWorker layer obtains directional clients in the following ways:

// 1. Use e.ource. Id to direct the message

self.addEventListener("message", e => {
	const client = await self.clients.get(e.source.id);
	client.postMessage('Messages to the page layer');
})

// 2. Direct the message to e.ource

self.addEventListener("message", e => {
	e.source.postMessage('Messages to the page layer');
})
Copy the code

2. ServiceWorkerRegistration.sync.register

The second way is to use sync to communicate from the page layer to the serviceWorker layer.

The downside of this communication is one-way and uncontrollable.

Once you register sync online, the onsync event in serviceWorker environment will be triggered immediately. ServiceWorker can process the event according to the specific logic. Sync will not complete until e.waituntil returns promise.resolve () and sync’s tag is cleared, otherwise the cycle will continue until E.chance == true.

// Page level environment

navigator.serviceWorker.ready.then(swReg= > {
	swReg.sync.register('synchronous tag')})Copy the code
// serviceWorker layer environment

self.addEventListener("sync", e => {
	if(e.tag == 'synchronous tag') {
		e.waitUntil(
	    	new Promise((res, rej) = > {
	    		// Logic processing...
	    		returnres(); }}})))Copy the code

3. MessageChannel

MessageChannel is a point-to-point MessageChannel that facilitates two-way communication of messages.

Constructor:

Constructors are simple and don’t take any arguments

var channel = new MessageChannel();
Copy the code

Properties:

  • MessageChannel.port1
  • MessageChannel.port2

The two ports in the property are implemented by the MessagePort interface, with the following methods:

  • postMessage
  • start
  • close

Event listener: messagePort.onMessage.

When sending messages, the postMessage in the environment is used.

// Page level environment

if(navigator.serviceWorker.controller) {
	var c = new MessageChannel();
	c.port1.onmessage = e= > {
		The message to port1 was received
	}
	
	// Send a message to port2
	navigator.serviceWorker.controller.postMessage('message', [c.port2])
}
Copy the code
/ / serviceWorker layer

self.addEventListener("message", e => {
	// Fetch MessagePort from e.posts
	e.ports[0] && e.ports[0].postMessage('Send a message to port1')})Copy the code

Note: The MessageChannel created channel will be affected by the serviceWorker stopWorker, causing the MessageChannel channel to close, meaning that the channel can only be used once. So every time you use MessageChannel to communicate, you create a new channel.


ServiceWorker communicates to the window

Just as the window page layer communicates to the serviceWorker environment, the serviceWorker environment layer also communicates to the page layer.

There are two main ways to communicate to the page layer in a serviceWorker environment.

1. BroadcastChannel

The first is BroadcastChannel, which means BroadcastChannel communication.

Constructor:

The constructor is simple; the channel argument is a string.

var channel = new BroadcastChannel(channel);
Copy the code

Properties:

  • BroadcastChannel.name: Channel name at construction time.

Events:

  • onmessage
  • onmessageerror

Methods:

  • postMessage()
  • close()

/ / page layer

var bc1 = new BroadcastChannel('c1');

bc1.onmessage = e= > {
	// The page layer receives the broadcast and processes it logically
}
Copy the code
/ / serviceWorker layer

var bc1 = new BroadcastChannel('c1');

bc1.postMessage('Send broadcast message');
Copy the code

2. client.postMessage

The second way is to get the corresponding client to postMessage.

If the corresponding SORCE client can be obtained from onMessage, two-way communication can be carried out. However, in the spontaneous case, only all clients can broadcast communication.

/ / serviceWorker environment

clients.matchAll({
  type: "window"
})
.then(windows= > {
  for (const win of windows) {
    win.postMessage('Send message to page'); }});Copy the code

Blog name: Wang Leping blog

CSDN blogs at blog.csdn.net/lecepin


Creative Commons Attribution – Non-commercial Use – No Deductive 4.0 International License