Detailed example of sharedWorker in JavaScript to achieve multi-page communication

Detailed example of sharedWorker in JavaScript to achieve multi-page communication

This is what happened. Today I was playing with GitHub. I first browsed some pages without logging in, and then logged in on a certain page. When you switch to other pages, you will see the following prompt:

So how is this done? We can think of one way is localStorage. When logging in to a certain page, modify the localStorage status. When other pages are displayed, read the latest status and then display a prompt:

// Login page localStorage.setItem('login', true);

// Other pages document.addEventListener("visibilitychange", function() {
	if (localStorage.setItem('login') === 'true') {
		alert('You are logged in, please refresh the page');
	}
}

However, GitHub did not do this, and no relevant fields could be found in localStorage. After some searching, I found that they implemented it using sharedWorker. Then let's take a look at sharedworker

What is sharedWorker

As the name implies, sharedWorker is a type of worker that can be shared by all pages of the same origin. Just like the Worker API, you can register a sharedWorker instance by passing in the js URL:

let myWorker = new SharedWorker('worker.js');

But it is different from ordinary Workers:
1 The same js url will only create one sharedWorker. If other pages use the same url to create sharedWorker, the created worker will be reused, and this worker will be shared by those pages.
2 sharedWorker sends and receives messages through port

Next, let's take a look at how messages are sent and received between the worker and the page.

messagePort

Suppose we have two js, ​​one is page.js running in the page, and the other is worker.js running in the worker. Then we need to register a sharedWorker in page.js, the code is as follows:

// page.js
let myWorker = new SharedWorker('worker.js');
// page sends a message through the worker port myWorker.port.postMessage('hum');
// page receives messages through worker port myWorker.port.onmessage = (e) => console.log(e.data);

// worker.js
onconnect = function(e) {
	const port = e.ports[0];
	port.postMessage('Hey');
	port.onmessage = (e) => {
		console.log(e.data);
	}
}

Debugging sharedWorker

In the above example, we used console.log in the worker to print the message from the page, so where can we see the printed log? We can enter `chrome://inspect in the browser address bar
, then select shared workers in the sidebar, and you can see all the workers currently running in the browser. Clicking inspect will open a developer tool, and then you can see the output log.

Here we see that our worker name is untitled, that's because the sharedworker constructor also supports passing in a second parameter as a name:

let myWorker = new SharedWorker('worker.js', 'awesome worker');

Post messages on multiple pages

Let’s go back to the example at the beginning of the article. We have implemented communication between the page and the worker. So how do we let the worker send messages to multiple pages? One idea is to cache the port as a port pool, so that when we need to broadcast a message to all pages, we can traverse the port and send the message:

// worker js
const portPool = [];
onconnect = function(e) {
	const port = e.ports[0];
	// Add port to portPool when connecting portPool.push(port);
	port.postMessage('Hey');
	port.onmessage = (e) => {
		console.log(e.data);
	}
}

function boardcast(message) {
	portPool.forEach(port => {
		port.portMessage(port);
	})
}

In this way, we have basically realized the function of broadcasting messages to multiple pages.

Clear invalid ports

There is a problem in the above implementation. After the page is closed, the port in the workerPool is not automatically cleared, resulting in a waste of memory. We can notify the shared worker that the page is about to be closed before the page is closed, and then have the worker remove the invalid messagePort from the portPool.

// Page window.onbeforeunload = () => {
  myWorker.port.postMessage('TO BE CLOSED');
};

// worker.js
const portPool = [];
onconnect = function(e) {
  var port = e.ports[0];
  portPool.push(port);
  port.onmessage = function(e) {
    console.log(e);
    if (e.data === 'TO BE CLOSED') {
      const index = ports.findIndex(p => p === port);
      portPool.splice(index, 1);
    }
    var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
    port.postMessage(workerResult);
  }
}

function boardcast(message) {
	portPool.forEach(port => {
		port.portMessage(port);
	})
}

In this way, we have implemented a simple sharedWorker for multi-page broadcasting. We can use it to broadcast the time:

setInterval(() => boardcast(Date.now()), 1000);

refer to

https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker/SharedWorker
https://github.com/mdn/simple-shared-worker

This is the end of this article about sharedWorker in JavaScript to achieve multi-page communication. For more related js sharedWorker multi-page communication content, please search 123WORDPRESS.COM's previous articles or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Javascript Web Worker using process parsing
  • Detailed explanation of Yii2 combined with Workerman's websocket example
  • Research on Web worker multithreading API in JavaScript
  • In-depth understanding of Worker threads in Node.js
  • How to use worker_threads to create new threads in nodejs
  • Javascript Worker sub-thread code example
  • Understanding the worker event API in JavaScript
  • How to use webWorker in JS

<<:  How to connect a Linux virtual machine to WiFi

>>:  CentOS installation mysql5.7 detailed tutorial

Recommend

How to install JDK 13 in Linux environment using compressed package

What is JDK? Well, if you don't know this que...

What is this in JavaScript point by point series

Understand this Perhaps you have seen this in oth...

Is it easy to encapsulate a pop-up component using Vue3?

Table of contents Summary put first: 🌲🌲 Preface: ...

Javascript asynchronous programming: Do you really understand Promise?

Table of contents Preface Basic Usage grammar Err...

Teach you how to monitor Tomcat's JVM memory through JConsoler

Table of contents 1. How to monitor Tomcat 2. Jav...

The complete implementation process of Sudoku using JavaScript

Table of contents Preface How to solve Sudoku Fil...

Nginx compiled nginx - add new module

1. View existing modules /usr/local/nginx/sbin/ng...

Detailed installation process of MySQL5.6.40 under CentOS7 64

MySQL5.6.40 installation process under CentOS7 64...

Example code for implementing verification code login in SMS API in Node

1. Node server setup + database connection The op...

Implementation of CSS3 button border animation

First look at the effect: html <a href="#...

Example code for converting html table data to Json format

The javascript function for converting <table&g...

How to Understand and Identify File Types in Linux

Preface As we all know, everything in Linux is a ...