This article is from the “muddy” share, the original title of the real-time news push collation, with optimization and changes.
1. Write it first
For developers familiar with instant messaging technology on the Web side, we review the underlying communication technology of IM on the Web side. From short polling, long polling, to SSE and WebSocket later, the threshold of use is getting lower and lower (early long polling Comet technology actually belongs to hack means, the threshold of use is not low), and the technical means are getting more and more advanced. The instant messaging experience on the web is getting better as a result.
But last week, while editing the third in a series of articles on IM Scanning login technologies, it occurred to me that these so-called “old technologies” of web instant messaging are not useless compared to the popular WebSocket. Take the scanning code login function in IM for example, using short polling technology is very appropriate, there is no need to cannon mosquitoes on the WebSocket.
Therefore, in many cases, there is no need to blindly pursue new technology, and the best one is suitable for the application scenario. While it’s important for developers of instant messaging technologies such as IM and push, it’s still helpful to know the “old technology” of Instant messaging on the Web, such as short polling and long polling. That’s why this article is so important.
2. Recommended reading
[1] Beginner’s Note: The most complete explanation of instant messaging technology on the Web
[2] Detailed explanation of the evolution of Web side communication mode: from Ajax and JSONP to SSE and Websocket
[3] Web side im technology inventory: short polling, Comet, Websocket, SSE
3. Introduction
For instant messaging systems such as IM/ push, the key is the ability to “communicate in real time”.
On the face of it, “real-time communication” means:
- 1) The client can actively send data to the server at any time;
- 2) The server can inform the client in real time when the content that the client cares about changes.
Compared with the traditional C/S request model, in “real-time communication”, the client does not need to send a request subjectively to obtain the content it cares about, but is “pushed” by the server.
** Note: the word “push” above is in quotation marks. In fact, in several existing technical implementation methods, the server is not really active push, but through some means to create a “real-time communication” illusion.
In terms of the existing technologies, there are mainly the following categories:
- 1) Client Polling: Short Polling in the traditional sense;
- 2) Server-side Polling: Long Polling (Long Polling);
- 3) One-way Server push: Server-sent Events (SSE);
- 4) Full duplex communication: WebSocket.
The following text will clarify these technical solutions for you.
4. This article supports Demo and code
To help readers understand this article, I have written a complete Demo that uses a simple chat room example to implement each of the four techniques mentioned above (the code has a few bugs, mainly for demonstration purposes, don’t mind).
Complete Demo source package download:
(Please download from the sync link attachment: www.52im.net/thread-3555…)
Demo (GIF) :
Interested can download their own study.
5. Understand Short Polling
Implementation principle of short polling:
- 1) The client sends a request to the server, the server returns data, and the client processes the data according to the data returned by the server;
- 2) The client continues to send requests to the server and repeat the above steps. If you do not want to put too much pressure on the server, you will generally set a request interval.
The logic is shown below:
** Advantages of using short polling: ** There is no additional development cost to base, request data, parse data, respond, that’s all, and then repeat.
The disadvantages are also obvious:
- 1) Constantly sending and closing requests will put great pressure on the server, because opening Http connections itself is a matter of resource consumption;
- 2) Polling time interval is not well controlled. If the real-time requirement is high, it is obvious that using short polling will have obvious disadvantages. If the interval is set too long, it will lead to message delay, and if it is too short, it will put pressure on the server.
Short polling customer code implementation (excerpt) :
var ShortPollingNotification = {
datasInterval: null,
subscribe: function() {
this.datasInterval = setInterval(function() {
Request.getDatas().then(function(res) {
window.ChatroomDOM.renderData(res);
});
}, TIMEOUT);
return this.unsubscribe;
},
unsubscribe: function() {
this.datasInterval && clearInterval(this.datasInterval);
}
}
**PS: ** Complete code, please see the section of “4, this article supporting Demo and code”.
The running effect of the supporting Demo in this paper is as follows (GIF) :
Here are the corresponding requests, noting that the number of requests in the lower left corner has been changing:
In the figure above, a request is sent every 1s, which looks good, but if you set timeout to 5s, the effect is compromised. As shown in the figure below.
Set timeout value to 5s (GIF) :
6. Understand Long Polling
6.1 Basic Principles
The basic principle of long polling:
- 1) The client sends a request and the server holds it;
- 2) Data will not be returned until the listening content changes, and the connection will be disconnected (or within a certain period of time, if the request is not returned, the connection will be automatically disconnected because of timeout);
- 3) The client continues to send the request and repeat the above steps.
The logic is shown below:
** Long polling is an improved version of short polling: ** It reduces the overhead of the client initiating an Http connection, instead actively checking whether the content of interest has changed on the server side.
So the nature of polling hasn’t changed much, except that:
- 1) The polling for content changes is changed from the client to the server (the client will send the request again after the connection is interrupted, which greatly reduces the number of initiating the connection compared with the short polling);
- 2) The client will only change the data when it changes. Compared with short polling, it does not receive all the data.
6.2 Code Implementation
Code implementation for long polling customers (excerpt) :
/ / the client
var LongPollingNotification = {
/ /…
subscribe: function() {
var that = this;
// Set the timeout period
Request.getV2Datas(this.getKey(),{ timeout: 10000 }).then(function(res) {
var data = res.data;
window.ChatroomDOM.renderData(res);
// The request will be sent again after the data has been successfully retrieved
that.subscribe();
}).catch(function(error) {
// Request will be sent again after timeout
that.subscribe();
});
return this.unsubscribe;
}
/ /…
}
The author uses Express, which does not support hold requests by default, so a express-Longpoll library is used to achieve this.
** If the server supports the hold request, it will poll itself for a certain period of time, and then determine whether to return new data by comparing key values.
Here are the specific ideas:
- 1) The client will return with an empty key for the first time, and the server will return the calculated contentKey to the client.
- 2) The client then sends a second request, with the contentKey returned from the first request as the key value, and then performs the next round of comparison;
- 3) If the two key values are the same, the request will be held for internal polling. If there is new content or client timeout, the connection will be disconnected.
- 4) Repeat the above steps.
The code is as follows:
// Server side
router.get(‘/v2/datas’, function(req, res) {
const key = _.get(req.query, ‘key’, ”);
let contentKey = chatRoom.getContentKey();
while(key === contentKey) {
sleep.sleep(5);
contentKey = chatRoom.getContentKey();
}
const connectors = chatRoom.getConnectors();
const messages = chatRoom.getMessages();
res.json({
code: 200,
data: { connectors: connectors, messages: messages, key: contentKey },
});
});
The following is to useexpress-longpollImplementation fragment of:
// mini-chatroom/public/javascripts/server/longPolling.js
function pushDataToClient(key, longpoll) {
var contentKey = chatRoom.getContentKey();
if(key ! == contentKey) {
var connectors = chatRoom.getConnectors();
var messages = chatRoom.getMessages();
long poll.publish(
‘/v2/datas’,
{
code: 200,
data: {connectors: connectors, messages: messages, key: contentKey},
}
);
}
}
long poll.create(“/v2/datas”, function(req, res, next) {
key = _.get(req.query, ‘key’, ”);
pushDataToClient(key, longpoll);
next();
});
intervalId = setInterval(function() {
pushDataToClient(key, longpoll);
}, LONG_POLLING_TIMEOUT);
**PS: ** Complete code, please see the section of “4, this article supporting Demo and code”.
For the sake of demonstration, I have changed the timeout for initiating a request from the client to 4s. Note the screenshot below:
As you can see, there are two ways to disconnect a connection: either a timeout or a request with data returned.
6.3 Iframe-based Long Polling Mode
This is another implementation of the long polling technique.
The specific principle of the scheme is as follows:
- 1) Insert an iframe in the page, the address points to the polling server address, and then place an execution function in the parent page, such as execute(data);
- 2) When the server changes content, it sends a script to the iframe;
- 3) Actively execute the methods in the parent page through the sent script to achieve the effect of push.
Due to lack of space, I will not give an in-depth introduction here. If you are interested, you can read the section “3.3.2 Iframe-based Data Flow” in the article “Beginner’s Notes: The Most Complete Explanation of the Principles of Instant Messaging Technology on the Web”.
7, What is Server-sent Events (SSE)
7.1 Basic Introduction
** From a purely technical point of view: ** The short polling and long polling technologies introduced in the last two sections cannot be actively pushed to the client by the server. The client takes the initiative to request the server to obtain the latest data.
SSE, described in this section, is a technology that actively pushes messages from the server.
SSE is essentially an HTTP long connection, but instead of sending a one-time packet to the client, it sends a stream in the format of
text/event-stream
. Instead of closing the connection, the client waits for a new data stream from the server, such as video playback.
In simple terms, SSE is:
- 1) SSE uses HTTP protocol, which is supported by all existing server software. WebSocket is a standalone protocol.
- 2) SSE is lightweight and easy to use; The WebSocket protocol is relatively complex.
- 3) SSE supports disconnection and reconnection by default, and WebSocket needs to be implemented by itself.
- 4) SSE is generally used to transmit text only, and binary data needs to be encoded and transmitted. WebSocket supports binary data transmission by default.
- 5) SSE supports user-defined message types sent.
The technical principle of SSE is shown in the figure below:
For the basic usage of SSE, please refer to SSE API documentation, the address is: developer.mozilla.org/en… A serializer… .
Currently, most modern browsers support SSE, except IE and older browsers:
(Image above: caniuse.com/?search=Ser…)
7.2 Code Implementation
/ / the client
var SSENotification = {
source: null,
subscribe: function() {
if(‘EventSource’inwindow) {
this.source = newEventSource(‘/sse’);
this.source.addEventListener(‘message’, function(res) {
const d = res.data;
window.ChatroomDOM.renderData(JSON.parse(d));
});
}
return this.unsubscribe;
},
unsubscribe: function() {
this.source && this.source.close();
}
}
// Server side
router.get(‘/sse’, function(req, res) {
const connectors = chatRoom.getConnectors();
const messages = chatRoom.getMessages();
const response = { code: 200, data: { connectors: connectors, messages: messages } };
res.writeHead(200, {
“Content-Type”:”text/event-stream”,
“Cache-Control”:”no-cache”,
“Connection”:”keep-alive”,
“Access-Control-Allow-Origin”: ‘*’,
});
res.write(“retry: 10000\n”);
res.write(“data: “+ JSON.stringify(response) + “\n\n”);
var unsubscribe = Event.subscribe(function() {
const connectors = chatRoom.getConnectors();
const messages = chatRoom.getMessages();
const response = { code: 200, data: { connectors: connectors, messages: messages } };
res.write(“data: “+ JSON.stringify(response) + “\n\n”);
});
req.connection.addListener(“close”, function() {
unsubscribe();
}, false);
});
Here’s what happens to the console. Note the response type:
Note the request type, as well as the EventStream message type:
**PS: ** More detailed information about SSE is not developed here. Interested students can read “SSE Technology in detail: A new HTML5 server Push event technology”, “Using WebSocket and SSE technology to achieve Web Side Message push”.
What is WebSocket
8.1 Basic Introduction
**PS: ** This section is quoted from “Instant Messaging practice on the Web: How to Make WebSocket down and reconnect Faster”. 3. Get to know WebSocket quickly.
WebSocket was introduced in 2008, became an international standard in 2011, and is now supported by all browsers (see Quick Start for Beginners: A Brief Tutorial on WebSocket). It is a new application layer protocol, is specially designed for web client and server real full-duplex communication protocol, can be compared with HTTP protocol to understand webSocket protocol.
(The picture is from “WebSocket In Detail (4) : Getting to the bottom of the relationship between HTTP and WebSocket (part 1)”)
Their differences:
- 1) The protocol identifier of HTTP is HTTP, and that of WebSocket is WS;
- 2) HTTP request can only be initiated by the client, the server cannot actively push messages to the client, but WebSocket can;
- 3) HTTP requests have the same origin restriction, and communication between different sources needs to cross domains, while WebSocket has no same origin restriction.
What are their similarities:
- 1) Both are communication protocols of the application layer;
- 2) The default port is the same, either 80 or 443;
- 3) Both can be used for communication between browser and server;
- 4) Both are based on TCP.
The relationship between TCP and TCP:
(Image from “Beginner’s Quick Start: WebSocket Tutorial”)
Read more about the relationship between Http and WebSocket:
WebSocket in Detail (4) : Getting to the bottom of HTTP and WebSocket relationship (part 1)
WebSocket details (5) : Getting to the bottom of HTTP and WebSocket relationship (Part 2)
About the relationship between WebSocket and Socket, you can read: WebSocket in detail (six) : Get to the bottom of the relationship between WebSocket and Socket.
8.2 Technical Features
The technical characteristics of WebSocket can be summarized as follows:
- 1) Two-way communication, designed mainly to reduce the cost of the number of HTTP connections in traditional polling;
- 2) Based on TCP protocol, HTTP protocol is used in the handshake stage, so it is not easy to shield the handshake and can pass various HTTP proxy servers;
- 3) Good compatibility with HTTP, can also use port 80 and 443;
- 4) The client can communicate with any server without the same origin restriction;
- 5) Can send text, can also send binary data;
- 6) The protocol identifier is WS (or WSS if encrypted) and the server URL is the URL.
The technical principle of WebSocket is shown in the figure below:
For WebSocket API knowledge, here is no longer explained, you can refer to: developer.mozilla.org/en-US/docs/…
8.3 Browser Compatibility
WebSocket is compatible and supports almost all modern browsers.
(Image above: caniuse.com/mdn-api_web…)
8.4 Code Implementation
The author here uses socket. IO, is based on WebSocket encapsulation, provides client and server support.
/ / the client
var WebsocketNotification = {
// …
subscribe: function(args) {
var connector = args[1];
this.socket = io();
this.socket.emit(‘register’, connector);
this.socket.on(‘register done’, function() {
window.ChatroomDOM.renderAfterRegister();
});
this.socket.on(‘data’, function(res) {
window.ChatroomDOM.renderData(res);
});
this.socket.on(‘disconnect’, function() {
window.ChatroomDOM.renderAfterLogout();
});
}
// …
}
// Server side
var io = socketIo(httpServer);
io.on(‘connection’, (socket) => {
socket.on(‘register’, function(connector) {
chatRoom.onConnect(connector);
io.emit(‘register done’);
var data = chatRoom.getDatas();
io.emit(‘data’, { data });
});
socket.on(‘chat’, function(message) {
chatRoom.receive(message);
var data = chatRoom.getDatas();
io.emit(‘data’, { data });
});
});
**PS: ** Complete code, please see the section of “4, this article supporting Demo and code”.
The response format is as follows:
8.5 In-depth Learning
With the increasing popularity of HTML5, the application of WebSocket is becoming more and more popular. It is easy to find learning materials about WebSocket on the Internet.
If you want to learn more about WebSocket in depth, the following articles are worth reading:
Quick Start for Beginners: WebSocket Tutorial
WebSocket In Detail (1) : A Preliminary Understanding of WebSocket Technology
WebSocket In Detail (II) : Technical Principles, Code Demonstrations and Application Cases
Details of WebSocket (iii) : In-depth Details of WebSocket Communication Protocol
WebSocket in Detail (4) : Getting to the bottom of HTTP and WebSocket relationship (part 1)
WebSocket details (5) : Getting to the bottom of HTTP and WebSocket relationship (Part 2)
WebSocket In Detail (6) : Probing the relationship between WebSocket and Socket
Theory and Practice: Understanding Communication Principle, Protocol Format and Security of WebSocket from Zero
Wechat small program how to use WebSocket to achieve long connection (complete source code)
8 Questions WebSocket Protocol: Quick Answers to WebSocket Hot Questions
Instant Messaging practice on the Web: How to Make your WebSocket Down and Reconnect Faster?
WebSocket from beginner to Master, half an hour is enough!
Introduction to WebSocket Core: 200 Lines of Code to Teach you how to masturbate a WebSocket Server
Long Connection Gateway Technology Topic (4) : IQiyi WebSocket Real-time Push Gateway Technology Practice
9. Summary of this paper
Short polling and long polling are relatively simple to implement, and are suitable for some message push with low real-time requirements. In the scenario with high real-time requirements, there will be delay and will bring greater pressure to the server.
SSE can only be server-side push messages, so it is suitable for projects that do not require two-way communication.
WebSocket currently has relatively low implementation cost and is suitable for duplex communication. It is more practical for multi-person online projects requiring high real-time performance.
This article has been published on the “instant Messaging technology circle” public account.
The link for the simultaneous release is: www.52im.net/thread-3555…