🎓 background
During the interaction between the browser and the server, the server communicates with the browser. For example, the server asynchronously processes the information and pushes the information to the browser.
However, not all background services have established websocket channels, so the common practice is to periodically query the browser, polling background data.
From a request point of view, polling is not concise and elegant because it is unnecessary for the browser to initiate a handshake and send a packet to the background service.
Is there a way that doesn’t require a WebSocket channel and doesn’t require polling to be “low”? SSE (Server-site Events) introduced in this article is concise and elegant enough.
🤔 ️ SSE is what
SSE stands for Server-sent Events. It is a way for a Server to push data to a client.
The essence of SSE is to continuously send streaming information through HTTP request, so that the server pushes information to the client. Similar to video streaming.
It is not a one-time packet, but will always wait for the server to push. So the client doesn’t close the connection and wait for the server to push it. This enables the server to push to the client.
🆚 SSE VS Websocket
Websocket is two-way communication (full duplex), where browsers <-> servers communicate with each other, making it more powerful and flexible.
SSE is one-way communication (half duplex), browser <- server, essentially downloading information.
contrast | advantages | disadvantages |
---|---|---|
Websocket |
1. Full duplex with more powerful functions |
1. The server needs to be supported again because it is complex 2. Reconnection requires additional deployment |
SSE |
1. The protocol is lightweight, and the server that supports HTTP supports it 2. Convenient reconnection is supported by default 3. Supports custom data types |
1. Half-duplex is not flexible enough |
Both have their own characteristics and are suitable for different places
💡 Use of SSE
Since SSE works on both client and server, the apis are divided into client and server.
Browser usage
Check whether it can be used
SSE’s API in the browser is on the EventSource object. In general, except for IE Edge, all major browsers support:
if (Boolean(window.EventSource)) {
// ...
}
Copy the code
Establish a connection to the server
The browser creates an EventSource instance and then initiates a connection to the server.
Of course, the URL can be in the same domain as the current url, or it can be cross-domain.
/ / the same url
let source = new EventSource(url);
// Take cookies across domains. Open the withCredentials property to indicate whether cookies are sent together.
let source = new EventSource(url, { withCredentials: true });
Copy the code
Change of state
The readyState property in the EventSource instance indicates the current connection state. You can take the following values.
The values | explain |
---|---|
0 |
Indicates that the connection is not established, or the disconnection is being reconnected |
1 |
Indicates that the connection has been established and data can be accepted |
2 |
Indicates that the connection is broken and will not be reconnected |
The basic use
When establishing a connection
, will triggeropen
Events, andjs
The usage of other events is basically the same
/ / onopen method
source.onopen = (event) = > {
// ...
}
// addEventListener
source.addEventListener('open'.(event) = > {
// ...
}, false);
Copy the code
When the message is received
, will triggermessage
Events, andjs
The usage of other events is basically the same.
/ / the onmessage method
source.onmessage = (event) = > {
const data = event.data;
// ...
};
// addEventListener
source.addEventListener('message'.(event) = > {
// Data is the data returned by the server. It is in text format
const data = event.data;
// ...
}, false);
Copy the code
When an error occurs
(for example, interrupt)error
Events, andjs
The usage of other events is basically the same.
/ / onerror method
source.onerror = (event) = > {
// ...
};
// addEventListener
source.addEventListener('error'.(event) = > {
// ...
}, false);
Copy the code
Close the connection
source.close();
Copy the code
Custom events
, which is triggered by defaultmessage
Event, but you can also customize the event so that it does not firemessage
Events. This example toinfo
Event listening
source.addEventListener('info'.(event) = > {
const data = event.data;
// ...
}, false);
Copy the code
Use of the server
Request header
The data the server sends to the browser is utF-8 encoded text, and the HTTP header has specific information. You must specify the content-type as event-Steam.
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
Copy the code
The data format
A message sent each time consists of several messages separated by \n\n. The types are as follows:
/ / data column
data: [value]\n
// Customize the information type
event: [value]\n
// Data identifier
id: [value]\n
// Maximum interval
retry: [value]\n
/ / comment
: [value]\n
Copy the code
contrast | describe | example |
---|---|---|
data |
Data content is represented by data, which can take up one or more lines and end with “\n\n” | data: begin message\n data: continue message\n\n |
event |
The event header indicates a custom data type, default if nomessage The event |
event: foo\n data: a foo event\n\n |
id |
Data identifiers are represented by IDS, which correspond to the number of each piece of data | id: msg1\n data: message\n\n |
retry |
By default, the browser does not send any message for three seconds to start reconnection. It can be used on the server sideretry Header information that specifies the maximum interval for communication |
retry: 10000\n |
|
Typically, the server sends a comment to the browser every once in a while to keep the connection going | : This is a comment |
Server-side implementation
Each server implementation is different. Here is the NodeJS solution implementation.
NodeJS implementation
// sse.js
const http = require("http");const http = require("http");
http.createServer(function (req, res) {
res.writeHead(200, {
"Content-Type": "text/event-stream"."Cache-Control": "no-cache"."Connection": "keep-alive"."Access-Control-Allow-Origin": The '*'}); res.write("retry: 1000\n");
res.write("event: connecttime\n");
res.write("data: " + (new Date()) + "\n\n");
interval = setInterval(function () {
res.write("data: " + (new Date()) + "\n\n");
}, 1000);
req.addListener("close".function () {
clearInterval(interval);
}, false);
}).listen(8080);
Copy the code
Startup and access
Just need Node sse.js to open it
node sse.js
Copy the code
And visit http://127.0.0.1:8080/ to access sse’s page!
🔚 epilogue
From polling to SSE, and then to SSE and Websocket technology selection, different scenarios with different schemes. There are long obstacles on the way to have it both ways.
Development is the same as growth. First “grow up”, then “grow up fast”, and finally “grow up well”. The development process is the same, replacing the string “grow” with “iterate”. The process is essential and the experience is completely different.
Hope to bring you some help, thank you for your time to read here ❤️.
Plus: Welcome to my blog