This article comes from the sharing of "God Go Go Go Go Go", the original title "Real-time News Push Sorting", there are optimizations and changes.
1. Write in front
For developers who are familiar with web-side instant messaging technology, we review the underlying communication technology of web-side IM, from short polling, long polling, to later SSE and WebSocket, the threshold for use is getting lower and lower (the early long round Inquiry Comet technology is actually a hack method, the threshold of use is not low), the technology is more and more advanced, the web-side instant messaging technology experience is getting better and better.
But last week when editing the third article of the "IM Scanning and Login Technology Special" series, I suddenly thought that these so-called web-side instant messaging "old technologies" are not useless compared to the popular WebSocket. Take the scan code login function in IM as an example, short polling technology is very suitable, there is no need to shoot mosquitoes on WebSocket.
Therefore, in many cases, there is no need to blindly pursue new technologies, and the ones that are suitable for the application scenarios are the best. For developers of instant messaging technologies such as im and message push on instant messaging networks, it is important to master WebSocket, but it is still helpful to understand these so-called “old technologies” of web-side instant messaging, such as short polling and long polling. This is also an important reason for organizing and sharing this article.
Learning Exchange:
5 groups for instant messaging/push technology development and communication: 215477170 [recommended]
Mobile IM development introductory article: "One entry is enough for novices: Develop mobile IM from scratch"
Open source IM framework source code: https://github.com/JackJiang2011/MobileIMSDK
(This article was published simultaneously at: http://www.52im.net/thread-3555-1-1.html )
2. Recommended reading
[1] Novice Getting Started Post: Detailed explanation of the principle of the most comprehensive Web-side instant messaging technology in history
[2] Explain the evolution of web-side communication: from Ajax and JSONP to SSE and Websocket
[3] Web-side instant messaging technology inventory: short polling, Comet, Websocket, SSE
3. Introduction
For instant messaging systems such as IM/message push, the key to the system is the "real-time communication" capability.
On the surface, "real-time communication" refers to:
1) The client can actively send data to the server at any time;
2) When the content that the client is concerned about changes, the server can notify the client in real time.
Similar to the traditional C/S request model, the client does not need to subjectively send a request to obtain the content that it cares about during "real-time communication", but is "pushed" by the server.
Note: The word "push" above is in quotation marks. In fact, in the existing several technical implementations, the server does not really push actively, but through certain means to create an illusion of "real-time communication" .
As far as the existing technologies are concerned, there are mainly the following categories:
1) Client polling: Short polling in the traditional sense (Short Polling);
2) Server-side polling: Long Polling;
3) One-way server push: Server-Sent Events (SSE);
4) Full duplex communication: WebSocket.
The following text will solve your confusion one by one for these several technical solutions.
4. Supporting Demo and code for this article
In order to help readers better understand the content of this article, the author specially wrote a more complete Demo. Demo will be implemented by the above four technical methods with an example of a simple chat room (the code has some bugs, mainly for demonstration purposes). Use it, don't mind).
Complete Demo source code package download:
(Please download from the synchronization link attachment: http://www.52im.net/thread-3555-1-1.html )
The running effect of Demo (motion picture):
If you are interested, you can download and study by yourself.
5. Understand short polling (Short Polling)
The realization 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 don't want to put too much pressure on the server, you will generally set a request interval.
The logic is shown in the figure below:
The advantages of using short polling: the basics do not require additional development costs, request data, parse the data, respond, nothing more, and then repeat.
The disadvantages are also obvious:
1) Constantly sending and closing requests will put more pressure on the server, because opening the Http connection itself is a resource-consuming thing;
2) The polling interval is not easy to control. If the required real-time performance is relatively high, obviously short polling will have obvious shortcomings. If the interval is set too long, it will cause message delay, and if it is too short, it will stress the server.
Code implementation of short polling client (excerpt from fragment):
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: For the complete code, please see the section "4. Supporting Demo and Code for this article" in this article.
The running effect of the Demo supporting this article is as follows (motion picture):
The following is the corresponding request. Note that the number of requests in the lower left corner has been changing:
In the above figure, a request will be sent every 1s. It seems that the effect is not bad, but if the value of timeout is set to 5s, the effect will be greatly reduced. As shown below.
The demo running effect when the timeout value is set to 5s (motion picture):
6. Understand long polling (Long Polling)
6.1 Basic principles
The basic principle of long polling:
1) The client sends a request, and the server will hold the request;
2) Until the monitored content changes, the data will be returned and the connection will be disconnected (or if the request is not returned within a certain period of time, the connection will be automatically disconnected due to timeout);
3) The client continues to send the request and repeat the above steps.
The logic is shown in the figure below:
Long polling is based on an improved version of short polling: it mainly reduces the overhead of initiating Http connections on the client side, and is changed to actively determine whether the content of interest has changed on the server side.
So in fact, the nature of polling has not changed much. The changes are:
1) The polling for content changes has been changed from the client to the server (the client will send the request again after the connection is interrupted, compared with the short polling, which greatly reduces the number of initiating connections);
2) The client will only make corresponding changes when the data changes. Compared with short polling, it is not full reception.
6.2 Code implementation
Code implementation of long polling client (excerpt from fragment):
// client
var LongPollingNotification = {
// ....
subscribe: function() {
var that = this;
// 设置超时时间
Request.getV2Datas(this.getKey(),{ timeout: 10000 }).then(function(res) {
var data = res.data;
window.ChatroomDOM.renderData(res);
// 成功获取数据后会再次发送请求
that.subscribe();
}).catch(function(error) {
// timeout 之后也会再次发送请求
that.subscribe();
});
return this.unsubscribe;
}
// ....
}
The author uses express, which does not support hold requests by default, so an express-longpoll library is used to implement it.
The following is a native implementation without a library (here is just the principle). The overall idea is: if the server supports the hold request, it will self-polling within a certain period of time, and then compare the key value during the period to determine whether to return New data.
The following are the specific ideas:
1) The client will bring an empty key value for the first time, this time it will return immediately to obtain the new content, and the server will return the calculated contentKey to the client;
2) Then the client sends a second request, with the contentKey returned for the first time as the key value, and then performs the next round of comparison;
3) If the two key values are the same, it will hold the request and perform internal polling. If there is new content or client timeout during the period, the connection will be disconnected;
4) Repeat the above steps.
code show as below:
// Service-Terminal
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 an implementation fragment using express-longpoll:
// 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: For the complete code, please see the section "4. Supporting Demo and Code for this article" in this article.
In order to facilitate the demonstration, I changed the timeout of the request initiated by the client to 4s, pay attention to the following screenshot:
As you can see, there are two ways to disconnect, either timeout or data return from the request.
6.3 Long polling mode based on iframe
This is another implementation scheme of long polling technology.
The specific principles of the program are:
1) Embed 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 content of the server changes, a script <script>parent.execute(JSON.stringify(data))</script> will be sent to the iframe;
3) Through the sent script, the method in the parent page is actively executed to achieve the push effect.
Due to lack of space, I will not give an in-depth introduction here. Interested students can read the section "3.3.2 Iframe-based data flow" in the article "Beginner Post: Detailed Explanation of the Principles of the Most Complete Web-side Instant Messaging Technology in History".
7. What is Server-Sent Events (SSE)
7.1 Basic introduction
From a purely technical point of view: In the short polling and long polling technologies introduced in the previous two sections, the server cannot actively push messages to the client, and the client actively requests the server to obtain the latest data.
The SSE introduced in this section is a technology that can actively push messages from the server.
The essence of SSE is actually a long HTTP connection, but it is not a one-time packet sent to the client, but a stream in the format of text/event-stream. Therefore, the client will not close the connection, but will always wait for the new data stream sent by the server. Video playback is an example of this.
Simply put, SSE is:
1) SSE uses HTTP protocol, which is supported by existing server software. WebSocket is an independent protocol.
2) SSE is lightweight and simple to use; the WebSocket protocol is relatively complex.
3) SSE supports disconnected reconnection by default, and WebSocket needs to be implemented by itself.
4) SSE is generally only used to transmit text. Binary data needs to be encoded and transmitted. WebSocket supports the transmission of binary data by default.
5) SSE supports custom message types sent.
The technical principle of SSE is shown in the figure below:
For the basic usage of SSE, please refer to the SSE API document, the address is: https://developer.mozilla.org/en ... _server-sent_events.
Currently, most modern browsers support SSE except IE and lower version browsers:
(The picture above is from: https://caniuse.com/?search=Server-Sent-Events )
7.2 Code implementation
// 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();
}
}
// Service-Terminal
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);
});
The following is the situation of the console, pay attention to observe the response type:
In the details, pay attention to the request type and the EventStream message type:
PS: More detailed information about SSE will not be expanded here. Interested students can read "Detailed SSE Technology: A New HTML5 Server Push Event Technology", "Using WebSocket and SSE Technology to Realize Web-side Message Push".
8. What is WebSocket
8.1 Basic introduction
PS: The content of this section is quoted from "Web-side Instant Messaging Practice Dry Goods: How to make WebSocket disconnect and reconnect faster? "3. Quickly understand WebSocket" in the article.
WebSocket was born in 2008 and became an international standard in 2011. It is now supported by all browsers (see "Quick Start for Newbies: A Concise Tutorial for WebSocket" for details). It is a brand-new application layer protocol, a true full-duplex communication protocol designed specifically for web clients and servers. It can be compared to the HTTP protocol to understand the websocket protocol.
(Picture quoted from "Detailed Explanation of WebSocket (4): Questioning the relationship between HTTP and WebSocket (Part 1)")
Their differences:
1) The protocol identifier of HTTP is http, and the identifier of WebSocket is ws;
2) HTTP requests can only be initiated by the client, the server cannot actively push messages to the client, while WebSocket can;
3) HTTP requests have homology restrictions, and communication between different sources needs to cross domains, while WebSocket has no homology restrictions.
Their similarities:
1) Both are application layer communication protocols;
2) The default port is the same, both are 80 or 443;
3) Both can be used for communication between browser and server;
4) All are based on TCP protocol.
The relationship between the two and TCP:
(Picture quoted from "Quick Start for Newbies: WebSocket Concise Tutorial")
For the relationship between Http and WebSocket, you can read in detail:
"Detailed Explanation of WebSocket (4): Questioning the relationship between HTTP and WebSocket (Part 1)"
"WebSocket Explained (5): The relationship between HTTP and WebSocket (Part 2)"
For the relationship between WebSocket and Socket, you can read: "Detailed Explanation of WebSocket (6): Questioning the relationship between WebSocket and Socket".
8.2 Technical features
The technical characteristics of WebSocket are summarized as follows:
1) Two-way communication is possible, the purpose of the design is mainly to reduce the overhead of the number of http connections in traditional polling;
2) Based on the TCP protocol, the HTTP protocol is used in the handshake phase, so it is not easy to block during the handshake, and it can pass through various HTTP proxy servers;
3) Good compatibility with HTTP, port 80 and 443 can also be used;
4) There is no homology restriction, the client can communicate with any server;
5) You can send text or binary data;
6) The protocol identifier is ws (if encrypted, it is wss), and the server website is the URL.
The technical principle of WebSocket is shown in the figure below:
Regarding the knowledge of WebSocket API, I will not explain it here, you can check it yourself: https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
8.3 Browser compatibility
WebSocket has good compatibility and basically supports all modern browsers.
(The above picture comes from: https://caniuse.com/mdn-api_websocket )
8.4 Code implementation
The author here uses socket.io, which is a WebSocket-based package that provides client and server support.
// 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();
});
}
// ...
}
// Service-Terminal
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: For the complete code, please see the section "4. Supporting Demo and Code for this article" in this article.
The response format is as follows:
8.5 In-depth study
With the increasing popularity of HTML5, the application of WebSocket is becoming more and more popular. Learning materials about WebSocket are easy to find on the Internet. Due to space limitations, this article will not go into this topic in depth.
If you want to learn more about all aspects of WebSocket, the following articles are worth reading:
"Quick Start for Novices: WebSocket Concise Tutorial"
"WebSocket Detailed Explanation (1): A Preliminary Understanding of WebSocket Technology"
"WebSocket Detailed Explanation (2): Technical Principles, Code Demonstrations and Application Cases"
"WebSocket Detailed (3): In-depth WebSocket Communication Protocol Details"
"Detailed Explanation of WebSocket (4): Questioning the relationship between HTTP and WebSocket (Part 1)"
"WebSocket Explained (5): The relationship between HTTP and WebSocket (Part 2)"
"Detailed Explanation of WebSocket (6): Questioning the relationship between WebSocket and Socket"
"Integrating Theory with Practice: Understanding the Communication Principle, Protocol Format, and Security of WebSocket from Zero"
"How to use WebSocket to realize long connection in WeChat applet (including complete source code)"
"Eight Questions about WebSocket Protocol: Quickly Answer Hot Questions about WebSocket"
"Web-side instant messaging practice dry goods: How to make your WebSocket disconnect and reconnect faster? 》
"WebSocket from beginner to proficient, half an hour is enough! 》
"WebSocket Hardcore Introduction: 200 lines of code, teach you to use a WebSocket server by hand"
"Special Topic on Long Connection Gateway Technology (4): Practice of iQiyi WebSocket Real-time Push Gateway Technology"
9. Summary of this article
The implementation cost of short polling and long polling is relatively simple, and it is suitable for some message pushes with low real-time requirements. In scenarios with high real-time requirements, there will be delays and will bring greater pressure to the server.
SSE can only push messages on the server side, so it is more suitable for projects that do not require two-way communication.
WebSocket currently has a relatively low implementation cost and is suitable for duplex communication. It is more practical for multi-person online projects that require high real-time performance.
160ac7d5b41d06 This article has been simultaneously published on the
▲ The link of this article on the official account is: click here to enter. The synchronous publishing link is: http://www.52im.net/thread-3555-1-1.html
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。