Web 实时推送技术

1、轮询(Polling)

  轮询是由客户端每隔一段时间向服务器端发起请求,查看服务器端是否产生新的数据。
优点:实现简单,只需在原有代码中添加定时器即可完成。
缺点:轮询时间间隔不好设计,过长过短都不好。过长,导致用户不能及时接收到更新的数据;过短,导致查询请求过多,增加服务器的负担。并且,连接数会很多,每次请求都会产生 HTTP 的 header,有效负载过低。

2、长轮询(Long-Polling)

  长轮询是对轮询的改进版,当服务器收到客户端发来的查询请求时,如果没有新数据就会阻塞请求,直到有新数据产生时才返回。当服务器响应或者连接超时后,客户端再次发起请求。
优点:对 Polling 做了优化,有很好的时效性,客户端代码无需修改。
缺点:保持连接会消耗资源;会有连接超时的情况。

3、长连接(基于iframe)

  iframe 流的方式是在页面中插入一个隐藏的 iframe,利用其src属性在服务器和客户端创建一个长连接,服务器向iframe源源不断的传输数据,来实时更新页面。
优点:浏览器兼容性好;消息能实时到达;
缺点:服务器维护一个长连接会增加开销;IE、Firefox会显示加载没有完成,图标会不停旋转。

4、webSocket

  WebSocket 是一种在单个TCP连接上进行全双工通信的协议。WebSocket 使得客户端和服务器端的数据交换变得简单,其允许服务端主动像客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

WebSocket 的特点:
  • 支持双向通信,实时性更强
  • 可以发送文本,也可以发送二进制数据
  • 减少通信量:只要建立起WebSocket 连接,就希望一直保持连接状态。

5、Demo

index.html




    
    
    Page Title
    


    

server.js

const http = require('http');
const fs = require('fs');
const path = require('path');
const url = require('url');

const basePath = path.join(__dirname, '/');
const server = http.createServer((req, res) => {
    if(req.url === '/longpolling'){
        // setTimeout(() => {res.end(new Date().toLocaleString())}, 10000);
        res.end(new Date().toLocaleString());
    } else if(req.url === '/'){
        fs.readFile(basePath + 'index.html',(err, data) => {
            if(err && err.code !== 'ENOENT'){
                throw err;
            }
            res.end(data);
        })

    } else if(req.url === '/polling'){
        res.end(new Date().toLocaleString());
    } else if(req.url.startsWith('/iframeStream')){
        let urlObj = url.parse(req.url, true);
        setInterval(() => {
            res.write(``)
        }, 1000)
    }
});

server.listen(8000);

WebSocket

const WebSocketServer = require('ws').Server;  // npm install ws

let wss = new WebSocketServer({port:8080});

let socket;

wss.on('connection', function(ws){
    socket = ws;
    ws.on('message', function(message){
        socket.send(new Date().toLocaleString());
        setInterval(() => {
            socket.send(new Date().toLocaleString());
        }, 1000)
    })
    ws.on('close', (message) =>{})
})

参考:Web 实时推送技术的总结(https://mp.weixin.qq.com/s/fnRAqxA1JCWppFGBAHwreA )

你可能感兴趣的:(javascript,实时推送,轮询,长轮询,长连接,websocket)