Xu Haoxing, front-end engineer of Wedoctor Front-end Technology Department. An ambitious young man who thinks the joy of life lies half in stillness and half in motion!

First, write first

Recently, I am doing a visual drag and drop project to build H5 pages. The whole project is divided into background configuration application and foreground rendering application. One business scenario requires that the foreground rendering application be able to render the configuration simultaneously while the page is configured. In other words, if you configure the background color to be red in the background, the foreground application will automatically change to red without having to refresh the page.

The core of this requirement is to keep data synchronized between the two front-end applications in real time, in other words, communication between the two front-end applications.

At first glance, the first thing that comes to mind is iframe, embed application 2 in application 1, and then call window.postMessage() for data communication. However, there are compatibility problems with iframe and too many pits. In addition, for two applications that do not have nested relationships, forced nesting will make subsequent developers unable to understand.

Here, my shallow amount of knowledge do not know what other methods, chose to look directly at the answer! My colleagues chose WebSocket to realize data synchronization between front and back. Like a bolt of lightning ⚡️, it broke the shackles and opened the door to a new world. (Is my knowledge accumulation is too shallow, woo woo).

What is WebSocket

I have heard the keyword WebSocket many times in my daily work and study, but my cognition of it is still superficial. So it is necessary to re-understand it systematically! The first thing you need to figure out is what a WebSocket is.

WebSocket is a network communication protocol in the same application layer as HTTP. It solves a drawback of HTTP: the server can only passively send data to the client, not actively push it. WebSocket makes it easier to exchange data between the client and the server, allowing the server to actively push data to the client.

In the WebSocket API, the browser and server only need to complete a handshake to establish a persistent connection and two-way data transfer. This is especially useful for services that require continuous data exchange, such as online games, real-time trading systems, etc.

This feature may not look simple, but it solves a lot of complex business problems, such as brushing weibo. We all know that scrolling through Twitter is a never-ending process, because every time you finish scrolling through the current item, the header area will say “Your followers have n new tweets.” And even if you don’t refresh the page in the process, this unread tweet alert will appear. This indicates that the weibo server pushed some data to the client when it did not receive the client’s request.

Let’s free up our brains and make a hypothesis. If WebSocket does not exist, what if we use HTTP to implement this requirement of microblogging?

If you implement this requirement using HTTP, polling is the only way to get new data to the server in a timely manner. However, both ordinary Polling and variant Long Polling have increased the consumption of server resources. Because the server needs to process HTTP requests from clients continuously for a certain amount of time.

This approach is not suitable as a solution because it can drag down servers and cause backend applications to crash when data is heavy.

At this time let us look back at WebSokcet, it can be a good solution to this problem. WebSocket allows the server to actively push messages to the client without origin restrictions.

How to use WebSocket

The above explained what a WebSocket is and how it can be used: the server actively pushes messages. Then, we need to introduce the use of WebSokcet.

To open a WebSocket connection, we need to create a new WebSocket in the URL using the special protocol WS:

let socket = new WebSocket("ws://javascript.info");
Copy the code

There is also an encrypted WSS :// protocol. Similar to HTTPS in WebSocket.

Once the socket is set up, we should listen for events on the socket. There are four events:

  • Open – Connection established
  • Message – Data is received
  • Error – WebSocket error
  • Close – The connection is closed

… If we want to send something, we can use socket.send(data) as an example:

let socket = new WebSocket("wss://javascript.info/article/websocket/demo/hello");

socket.onopen = function(e) {
  alert("[open] Connection established");
  alert("Sending to server");
  socket.send("My name is John");
};

socket.onmessage = function(event) {
  alert(`[message] Data received from server: ${event.data}`);
};

socket.onclose = function(event) {
  if (event.wasClean) {
    alert(`[close] Connection closed cleanly, code=${event.code} reason=${event.reason}`);
  } else {
    // For example, the server process is killed or the network is interrupted
    // In this case, event.code is usually 1006
    alert('[close] Connection died'); }}; socket.onerror =function(error) {
  alert(`[error] ${error.message}`);
};
Copy the code

For demonstration purposes, in the example above, you run a small server, server.js, written in Node.js. It responds with “Hello from server, John” and waits five seconds to close the connection.

So you see the sequence of events: Open → Message → Close.

This is WebSocket, and we can already communicate with WebSocket. Simple, isn’t it?

4. Communication between front and back

1. Apply the role model

When we need to communicate data between foreground and background applications, we first need to know what their roles are.

At first I assumed that one was a “server” and the other a “client”. So how do you determine which is the server? And what if multiple applications need to keep data in sync? These issues led me to redefine their role.

To think more generally, we need a single process to act as the server, with the rest of the front-end application as the client. In this way, no matter how many clients there are, data synchronization between applications can be mediated through the server. The architecture diagram is as follows:

As you can see from the figure above, the socket process needs to be started when one of the client applications is started. The rest of the client applications then connect to the socket process and exchange data.

2. New problem: How to start a socket process

Now that the architectural logic is known, new problems arise. We know from the socket example that to establish a socket connection, we need a URL string at the beginning of the WS/WSS protocol. Where do I need to get this string from?

Let’s get back to the essence of the question: how do I set up a socket connection?

let socket = new WebSocket("ws://javascript.info");
Copy the code

The above line of code is the simplest way to establish a socket connection. But behind this line of code lies a hidden role: the server.

So how can we start a socket service and establish a connection between the client and the backend service? When the problem came up, I was looking for a built wheel in the first place. IO (server) and socket.io. Client (client).

3. Server-side code

// ws/index.js
const server = require('http').createServer()
const io = require('socket.io')(server)

// Bind events
io.on('connect'.socket= > {
  console.log('Server connection established successfully! ')
  socket.on('disconnet'.() = > {
    console.log('Server detects disconnection')
  })
  socket.on('transportData'.(data) = > {
    console.log('Server detects data transfer', data)
    io.sockets.emit('updateData', data)
    console.log('Server emit event updateData')})})// Start the server program to listen
server.listen(8020.() = > {
  console.log('==== socket server is running at 1234 port ====')})Copy the code

The above is the server socket program simple code, note that here we use socket.io. Socket. IO encapsulates Websocket, Polling mechanism and other real-time communication methods as common interfaces, and implements corresponding codes of these real-time mechanisms on the server side. That is, Websocket is just a subset of the socket. IO implementation of real-time communication. It solves the problem of compatibility between different browsers and allows us to focus more on business logic.

The core of this code is listening for (on) and throwing (emit) events. The event emitted by it will be listened to by all connected clients, provided that each client does event listening.

4. Client code

// client1.vue <script> import io from 'socket.io-client' export default { ... Mounted () {const socket = IO ('http://127.0.0.1:8020') socket.on('connect', () => {console.log('client1 successfully established connection ') console.log('client1 successfully transferred data ') socket.emit('transportData', {name: 'xuhx'})}) socket.on('updateData', (data) => {console.log('client1 listening for data updates ', data)})} </script>Copy the code

The above code is client 1 code, mainly do is to establish a connection with the socket server, and then listen and throw the corresponding event.

// client2.vue <script> import io from 'socket.io-client' export default { ... Mounted () {const socket = IO ('http://127.0.0.1:8020') socket.on('connect', () => {console.log('client2 succeeded in setting up a connection ')}) socket.on('updateData', (data) => {console.log('client2 heard data update ', data) }) } } </script>Copy the code

When the socket process throws an updateData event, both client1 and Client2 can listen for the event and get the data passed.

From the above data transmission diagram, we can see that the client can emit custom events through the socket and then be monitored by other clients to keep data synchronization between client applications.

Other means of communication

No solution is perfect; all are better suited to a particular business scenario. Different solutions are required for different front-end business scenarios. So besides WebSocket, what other solutions can be used for communication between front-end applications? Below I combine the actual development work to enumerate.

The first step is to categorize the business scenarios: whether the front-end communication across pages is homologous. This classification is easy to understand if two communicating pages belong to the same front-end project. There are many ways for homologous pages to communicate, we mainly solve the communication between non-homologous pages.

1. Cookie

If the root domain names of application A and application B are the same, but their sub-domain names are different, for example, tieba.baidu.com and waimai.baidu.com. So how do you transfer data between these two application pages? Some students will think of sessionStorage and LocalStorage, but the basis of their storage is homologous. Application A cannot access the sessionStorage of application B. But the corresponding Cookie can meet our needs, because cookies can set the storage Domain. If its domain is set to the root domain, application A can access the Cookie data under application B.

Cookies are not suitable for storing large amounts of data because cookies are carried with each request, which may waste bandwidth resources. It is very suitable for the transmission of A certain state, such as whether the user has received the membership card in application A, and application B reads the state of receiving through cookies for processing the corresponding business logic.

2. iframe + window.postMessage()

If the root domain names of application A and application B are the same, we can use cookies. However, sometimes we have a product line with two different domains and want all the pages under them to communicate seamlessly. So what to do?

To do this, use an IFrame that is not visible to the user as the “bridge.” Since the origin restriction can be ignored between an iframe and the parent page by specifying origin, it is possible to embed an IFrame in the page (for example: http://sample.com/bridge.html), but the iframe by using a url, therefore belongs to the homologous page. Window.postmessage () is then used to communicate between the outer application and the embedded application.

3. Server Sent Events

The Server-Sent Events specification describes a built-in class EventSource that maintains a connection to the Server and allows Events to be received from it. Similar to WebSocket, the connection is persistent.

But there are several important differences between the two:

WebSocket EventSource
Bidirectional: Both client and server can exchange messages Unidirectional: Only the server can send messages
Binary and text data Text-only data
The WebSocket protocol General HTTP protocol

Compared to WebSocket, EventSource is a less powerful way to communicate with the server.

Why do we use it?

The main reason: simplicity. In many applications, WebSocket is overkill.

We need to receive a stream of data from the server: chat messages, market prices, etc. That’s what EventSource does well. It also supports automatic reconnection, which in WebSocket we had to implement manually. Moreover, it is plain old HTTP, not a new protocol.

4. The front end

The micro front end is a cutting-edge technology that I’ve heard about for a long time but haven’t had a chance to use. And listen to the introduction of colleagues, now the use of micro front end there are many pits. But it is one of the exploration directions for communication and collaboration between applications. Specific use and train of thought need everybody to explore by oneself ah.

I’ve listed three other ways of communicating between non-homologous pages. In fact, when I was searching for relevant materials, I found many ways of peer combing. But I find it hard to remember so many ways, and some of them are almost impossible to use, adding to the burden of memory. So I just listed here the mainstream good way, a fresh eat all day ~ ~

Six, the summary

Data communication between the two front-end projects can be implemented through WebSocket. The project starts a separate process that acts as the socket server. The front-end application that needs data communication establishes a connection with the socket process in the page, and realizes data synchronization between two different applications by emit custom events and listening for corresponding events. This article is actually the basic use of WebSocket, combined with a summary of the specific business development. Hope to be able to meet the relevant needs of friends to help.

7. Recommended reading

  1. [Long Polling][zh.javascript.info/long-pollin…]
  2. Long connection, short connection, long polling, and WebSocket
  3. WebSocket is introduced
  4. 3 minutes Access socket. IO
  5. WebSocket tutorial — Ruan Yifeng
  6. Front-end cross-page communication, what do you know?

Go to the online diagnosis and treatment platform of Wedoctor Internet hospital, make a quick consultation, and find a top three doctor for you in 3 minutes.