| 
                        副标题[/!--empirenews.page--]
                         前言
 随着 Web 的发展,用户对于 Web 的实时推送要求也越来越高 ,比如,工业运行监控、Web 在线通讯、即时报价系统、在线游戏等,都需要将后台发生的变化主动地、实时地传送到浏览器端,而不需要用户手动地刷新页面。本文对过去和现在流行的 Web 实时推送技术进行了比较与总结。 
一、双向通信
HTTP 协议有一个缺陷:通信只能由客户端发起。举例来说,我们想了解今天的天气,只能是客户端向服务器发出请求,服务器返回查询结果。HTTP 协议做不到服务器主动向客户端推送信息。这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦。在WebSocket协议之前,有三种实现双向通信的方式:轮询(polling)、长轮询(long-polling)和iframe流(streaming)。 
1.轮询(polling) 
 
轮询是客户端和服务器之间会一直进行连接,每隔一段时间就询问一次。其缺点也很明显:连接数会很多,一个接受,一个发送。而且每次发送请求都会有Http的Header,会很耗流量,也会消耗CPU的利用率。 
    - 优点:实现简单,无需做过多的更改
 
    - 缺点:轮询的间隔过长,会导致用户不能及时接收到更新的数据;轮询的间隔过短,会导致查询请求过多,增加服务器端的负担
 
 
- // 1.html 
 -  
 - <div id="clock"></div> 
 -  
 - <script> 
 -  
 - let clockDiv = document.getElementById('clock'); 
 -  
 - setInterval(function(){ 
 -  
 - let xhr = new XMLHttpRequest; 
 -  
 - xhr.open('GET','/clock',true); 
 -  
 - xhr.onreadystatechange = function(){ 
 -  
 - if(xhr.readyState == 4 && xhr.status == 200){ 
 -  
 - console.log(xhr.responseText); 
 -  
 - clockDiv.innerHTML = xhr.responseText; 
 -  
 - } 
 -  
 - } 
 -  
 - xhr.send(); 
 -  
 - },1000); 
 -  
 - </script> 
 -  
 - //轮询 服务端 
 -  
 - let express = require('express'); 
 -  
 - let app = express(); 
 -  
 - app.use(express.static(__dirname)); 
 -  
 - app.get('/clock',function(req,res){ 
 -  
 - res.end(new Date().toLocaleString()); 
 -  
 - }); 
 -  
 - app.listen(8080); 
 
  
启动本地服务,打开http://localhost:8080/1.html,得到如下结果: 
 
2.长轮询(long-polling) 
 
长轮询是对轮询的改进版,客户端发送HTTP给服务器之后,看有没有新消息,如果没有新消息,就一直等待。当有新消息的时候,才会返回给客户端。在某种程度上减小了网络带宽和CPU利用率等问题。由于http数据包的头部数据量往往很大(通常有400多个字节),但是真正被服务器需要的数据却很少(有时只有10个字节左右),这样的数据包在网络上周期性的传输,难免对网络带宽是一种浪费。 
    - 优点:比 Polling 做了优化,有较好的时效性
 
    - 缺点:保持连接会消耗资源; 服务器没有返回有效数据,程序超时。
 
 
- // 2.html 服务端代码同上 
 -  
 - <div id="clock"></div> 
 -  
 - <script> 
 -  
 - let clockDiv = document.getElementById('clock') 
 -  
 - function send() { 
 -  
 - let xhr = new XMLHttpRequest() 
 -  
 - xhr.open('GET', '/clock', true) 
 -  
 - xhr.timeout = 2000 // 超时时间,单位是毫秒 
 -  
 - xhr.onreadystatechange = function() { 
 -  
 - if (xhr.readyState == 4) { 
 -  
 - if (xhr.status == 200) { 
 -  
 - //如果返回成功了,则显示结果 
 -  
 - clockDiv.innerHTML = xhr.responseText 
 -  
 - } 
 -  
 - send() //不管成功还是失败都会发下一次请求 
 -  
 - } 
 -  
 - } 
 -  
 - xhr.ontimeout = function() { 
 -  
 - send() 
 -  
 - } 
 -  
 - xhr.send() 
 -  
 - } 
 -  
 - send() 
 -  
 - </script> 
 
  
                        (编辑:91站长网) 
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! 
                     |