Scenario: The backend update data is pushed to the client (the Java part uses the Tomcat server).
There are many solutions for pushing data in the backend, such as polling, Comet, and WebSocket.
1. Polling is the lowest development cost for the backend, which means processing Ajax requests and returning data in the traditional way. When I was in school, the laboratory projects always used polling because it is the safest and easiest to implement. However, the waste of communication resources caused by polling cannot be ignored. Regardless of whether the data changes or not, the request will be sent and responded as usual, and each HTTP request will have a long header information.
2. The concept of Comet is a long connection. After the client sends a request, the backend keeps the connection until the connection timed out or the backend returns data, and then re-establishes the connection, effectively transferring the communication resources to the server, which actually consumes server resources.
3. WebSocket is a full-duplex communication technology provided by HTML5. It realizes communication between the client and the server through "handshake". It has good real-time performance and a small head. The currently supported browsers are as follows:
The ideal situation is to use the combination of WebSocket and Comet, and use the Comet method to downgrade browsers such as IE8. But in this way, the backend needs to implement two logics for processing requests, namely WebSocket and Comet. Therefore, this article has added Node.js. The reason for doing this is to transfer the logic that handles WebSocket (or Comet) to the Node.js part, and not "induce trouble" to the backend, because in actual situations, it is not easy for front-end developers to promote back-end developers. Node.js is the intermediate layer for communication between the browser and the Java business logic layer, connecting the client to Tomcat, and communicating with Tomcat through Socket (it is Socket, not WebSocket, and the backend needs to implement the Socket interface.
On the client, WebSocket and Comet are implemented through Socket.io. Socket.io will choose the appropriate implementation method (WebSocket, long pull..) for different browser versions or different clients. The introduction of Socket.io makes it easy to handle WebSocket (or long connection). Socket.io
The client introduces socket.io:
<script src="static/js/socket.io.js"></script>
Client JavaScript code:
var socket = io.connect('127.0.0.1:8181'); // Send data to the server socket.emit('fromWebClient', jsonData);// Receive data from the server socket.on('pushToWebClient', function (data) { // do sth. });Node.js server code:
var http = require('http'), app = http.createServer().listen('8181'), io = require('socket.io').listen(app); io.sockets.on('connection', function (socketIO) { // Receive data from the client socketIO.on('fromWebClient', function (webClientData) { // do sth. }); // Client disconnect socketIO.on('disconnect', function () { console.log('DISCONNECTED FROM CLIENT'); }); // Send data to the client socketIO.emit('pushToWebClient', jsonData); });Establishing a good connection between the client and the Node.js server is only the first step. The following also requires establishing a connection between the Node.js server and the Java business logic layer. At this time, the Node.js server serves as a client to send a TCP connection request to Tomcat. After the connection is successful, the Node.js server and Tomcat establish a full duplex channel, and it is the only one. No matter how many client requests are, they are forwarded from the Node.js server to Tomcat; similarly, the data pushed by Tomcat is also distributed to each client via the Node.js server.
There is a problem here, that is, after both WebSocket connections and Socket connections are established, the two connections are blocked. Tomcat doesn't know which WebSocket connection sent the data, nor does it know which client sent the data. Of course, Node.js can use the session id to send to Tomcat to identify which client it is, but this article uses another method.
When a client establishes a WebSocket connection with Node.js, each connection will contain an instance, which is called socketIO here. Each socketIO has an id attribute to uniquely identify this connection, which is called socket_id here. Using socket_id, a mapping table is established on the Node.js server to store the mapping relationship between each socketIO and socket_id. When the Node.js server sends data to Tomcat, the socket_id is brought with it, and then the Java part carries out a series of processing, then encapsulates the different data required by each client and returns it. The returned data must have a corresponding relationship with socket_id. In this way, when the Node.js server receives the data sent by Tomcat, it is distributed to different clients by different socketIO through the aforementioned mapping table.
Node.js server code:
var http = require('http'), net = require('net'), app = http.createServer().listen('8181'), io = require('socket.io').listen(app), nodeServer = new net.Socket(); // Connect to Tomcat nodeServer.connect(8007, '127.0.0.1', function() { console.log('CONNECTED'); });// Store the client's WebSocket connection instance var aSocket = {}; // Create a connection with the client io.sockets.on('connection', function (socketIO) { // Receive data from the client and send it to Tomcat socketIO.on('fromWebClient', function (webClientData) { // Store to the mapping table aSocket[socketIO.id] = socketIO; // Add socket_id to the data sent to Tomcat webClientData['sid'] = socketIO.id; // Send data of String type to Tomcat nodeServer.write(JSON.stringify(webClientData)); }); // Disconnect socketIO.on('disconnect', function () { console.log('DISCONNECTED FROM CLIENT'); }); }); }); // Receive data from Tomcat nodeServer.on('data', function (data) { var jsonData = JSON.parse(data.toString()); // Distribute data to client for (var i in jsonData.list) { aSocket[jsonData.list[i]['sid']].emit('pushToWebClient', jsonData.list[i].data); } });The above code omits some logic, such as the data received by the Node.js server from Tomcat is divided into two types, one is the data pushed, and the other is the data responding to the request. Here, the data pushed is uniformly processed.
When processing communication, the data sent by Node.js to Tomcat is in String format, and the data received from Tomcat is a Buffer object (eight-byte), which needs to be converted into String and then converted into json and sent to the client.
This article just gives a simple example of such two connections, and many things need to be added to the specific business. Since Node.js is introduced into the project, the front-end needs to undertake more things, such as processing, caching, and even adding a lot of business logic.