Web server push technology initiative

HTTP protocol follows the classic client - server model, the client sends a request and waits for a response from the server side, the server responds only after receiving the request from the client, can not take the initiative to send the data to the client.

The client wants to get in without refreshing the page in real time to the latest data on the server side, through the following ways:

  1. polling
  2. Long polling
  3. HTTP流
  4. SSE
  5. Web Sockets

1. Polling

The client (browser) sends a request to the timing server, obtain the latest data. Can be achieved by triggering ajax request in a timer:

//每两秒触发一次ajax请求,获取最新的数据
setInterval(function(){
   //do some ajax call here to retrieve latest data
},2000);
 

advantage:

Simple, JS end to make some changes can be, without any back-end service changes

Disadvantages:

Polling interval is too long, the user can cause the received data can not be timely updated; polling interval is too short, a query request will cause excessive increase in the burden on the server

2. Long polling

Long polling method implementation works as follows:

  1. The client initiates a request to the server (http request)
  2. Server connection remains open until the data can be sent to the client, and then returns the requested (http response)
  3. After the client receives the data returned by the server, processing data, and immediately initiate a new request
  4. ...
 
//server端示例(nodejs)
var aTargets = [];
app.get('/notification', function(req, res) {
    aTargets.push(res);
  //res.end();  这里不调用res.end(),让http request连接一直存活着
})

//此方法会在有新的数据时调用
onNewNotification : function (data) {
  aTargets.forEach(function(res){
    res.send(data);//当有新的数据时,再调用res.send(data)返回最新的数据,结束一次http请求
  })
}

advantage:

  • Can timely access to the latest data
  • Compared to the polling strategy to reduce the number of requests

Disadvantages:

Always connected to the server, can not be released, due to the limited number of connections that can be processed by a server, when the server reaches the upper limit of the processing, the server can not respond to new requests

3. HTTP流

HTTP streaming different from the polling and long polling method, it is within the client page life cycle, only need to use a HTTP connection, that is, only send a request to the server for this request, the server will keep the HTTP connection (not return response), and periodically sends data to the browser.

//server端示例(nodejs)
let express = require("express");
let app = express();

app.use(express.static("resources"));
app.get("/httpstream",function(req, res){
    var x = 0;
    res.setHeader('Connection', 'Transfer-Encoding');
  res.setHeader('Content-Type', 'text/html; charset=utf-8');
  res.setHeader('Transfer-Encoding', 'chunked');//声明数据传输编码为chunked,让浏览器及时处理
    setInterval(function(){
        res.write(x+++"|"); //每隔2s向客户端发送一次数据
    },2000);
});

app.listen(3000);

After the server receives the request, the client every two seconds to output a bit of text, but will not use res.end()or res.send()end the current http request.

//客户端示例js
var xhr = new XMLHttpRequest();
var received = 0;
var result = "";
xhr.open("get","/httpstream",true);
xhr.onreadystatechange = function () {
  if (xhr.readyState == 3) { //readystate 3 表示正在解析数据
    result = xhr.responseText.substring(received);//截取最新的数据
    received += result.length;
    console.log(result);
  }
}
xhr.send();

With receives data from the server, the client readyStatewill periodically become 3, responseTextcontaining all data sources. By receivedpreviously recorded data length it has been treated, and then responseTexttaken latest data.

 

advantage:

页面的整个生命周期内,只需要建立一个http连接

缺点:

  • 如果接入的客户端过多,服务器端会因为http连接有限而无法为新的客户端提供服务
  • 客户端接收到的数据流会越来越大,最终可能会引发页面的性能问题

4. SSE

SSE(Server-Sent Events)是基于HTTP实现的一套服务器向客户端发送数据的API。他是针对上面说到的三种方法(轮询,长轮询,HTTP流)的一个标准API实现。

使用SSE API可以创建到服务器端的但相连接,服务器可以通过这个连接发送任意数据。它有以下特点:

  • 断开自动连接
  • 服务器响应的MIME类型必须是text/event-stream
  • 需要浏览器API支持(参考浏览器兼容性)

使用方法如下:

//客户端js
var source = new EventSource(url);
//建立连接时触发
source.onopen = function () {
  //do something here
};
//从服务器端接收到新的事件时触发
source.onmessage = function (event) {
  var data = event.data; //服务器返回的数据存放在event.data中
};
//连接异常时触发
source.onerror = function () {
  //do something here
};

客户端创建一个EventSource对象,绑定到对应的url,然后监听该对象的onmessage事件就可以获取到最新的数据。

//server端示例(nodejs)
let express = require("express");
let app = express();

app.use(express.static("resources"));
app.get("/httpstream",function(req, res){
    var x = 0;
  res.writeHead(200, {
      "Content-Type":"text/event-stream",
      "Cache-Control":"no-cache",
      "Connection":"keep-alive"
    });
  //每个1s往客户端发送一条数据
  setInterval(function(){
      res.write("data: " + x++ + "\n\n");//发送的数据格式必须是"data: <内容>/n/n"
  },1000);
});

app.listen(3000);

5. Web Sockets

不同于SSE,Web Sockets 采用了一套全新的协议(ws/wss)来建立客户端到服务器端的全双工、双向通信连接。

关于web sockets的使用,这篇文章:http://www.ruanyifeng.com/blog/2017/05/websocket.html 已经介绍的非常全面了,我就不再赘述。

优点:

  • 双向通信,实时连接
  • 相较于HTTP请求更加高效(不需要握手,连接始终存在;无需携带头部信息)

缺点:

  • 稳定性和成熟度问题

建议:

在使用的过程中,请根据产品将来的使用环境(支持的浏览器类型、版本),使用场景(双向通信、单向通信)这些点,并结合每一种方法的优缺点去考虑,然后选取对应的策略。

 

******************转摘:https://www.jianshu.com/p/72372741df5f

Guess you like

Origin www.cnblogs.com/linybo/p/12084158.html