作者 | 浪里行舟

责编 | 郭芮

人工智能的现状及今后发展趋势如何? 

https://edu.csdn.net/topic/ai30?utm_source=csdn_bw

随着 Web 的发展,用户对于 Web 的实时推送要求也越来越高 ,比如,工业运行监控、Web 在线通讯、即时报价系统、在线游戏等,都需要将后台发生的变化主动地、实时地传送到浏览器端,而不需要用户手动地刷新页面。本文对过去和现在流行的 Web 实时推送技术进行了比较与总结。

纸上得来终觉浅,建议大家动手敲敲代码——本文完整的源代码请猛戳Github博客(https://github.com/ljianshu/Blog)。

双向通信

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>

3.iframe流(streaming)

iframe流方式是在页面中插入一个隐藏的iframe,利用其src属性在服务器和客户端之间创建一条长连接,服务器向iframe传输数据(通常是HTML,内有负责插入信息的javascript),来实时更新页面。

  • 优点:消息能够实时到达;浏览器兼容好;

  • 缺点:服务器维护一个长连接会增加开销;IE、chrome、Firefox会显示加载没有完成,图标会不停旋转。

// 3.html
<body>
    <div id="clock"></div>
    <iframe src="/clock" style="display:none"></iframe>
</body>

//iframe流
let express = require('express')
let app = express()
app.use(express.static(__dirname))
app.get('/clock'function(req, res){
  setInterval(function(){
    let date = new Date().toLocaleString()
    res.write(`
       <script type="text/javascript">
         parent.document.getElementById('clock').innerHTML = "${date}";//改变父窗口dom元素
       </script>
     `)
  }, 1000)
})
app.listen(8080)

启动本地服务,打开http://localhost:8080/3.html,得到如下结果:

上述代码中,客户端只请求一次,然而服务端却是源源不断向客户端发送数据,这样服务器维护一个长连接会增加开销。

以上我们介绍了三种实时推送技术,然而各自的缺点很明显,使用起来并不理想,接下来我们着重介绍另一种技术——websocket,它是比较理想的双向通信技术。

WebSocket

1.什么是websocket?

WebSocket是一种全新的协议,随着HTML5草案的不断完善,越来越多的现代浏览器开始全面支持WebSocket技术了,它将TCP的Socket(套接字)应用在了webpage上,从而使通信双方建立起一个保持在活动状态连接通道。

一旦Web服务器与客户端之间建立起WebSocket协议的通信连接,之后所有的通信都依靠这个专用协议进行。通信过程中可互相发送JSON、XML、HTML或图片等任意格式的数据。由于是建立在HTTP基础上的协议,因此连接的发起方仍是客户端,而一旦确立WebSocket通信连接,不论服务器还是客户端,任意一方都可直接向对方发送报文。

初次接触 WebSocket 的人,都会问同样的问题:我们已经有了 HTTP 协议,为什么还需要另一个协议?

2.HTTP的局限性

HTTP是半双工协议,也就是说,在同一时刻数据只能单向流动,客户端向服务器发送请求(单向的),然后服务器响应请求(单向的)。

服务器不能主动推送数据给浏览器。这就会导致一些高级功能难以实现,诸如聊天室场景就没法实现。

3.WebSocket的特点

  • 支持双向通信,实时性更强;

  • 可以发送文本,也可以发送二进制数据;

  • 减少通信量:只要建立起WebSocket连接,就希望一直保持连接状态。和HTTP相比,不但每次连接时的总开销减少,而且由于WebSocket的首部信息很小,通信量也相应减少了。

相对于传统的HTTP每次请求-应答都需要客户端与服务端建立连接的模式,WebSocket是类似Socket的TCP长连接的通讯模式,一旦WebSocket连接建立后,后续数据都以帧序列的形式传输。

在客户端断开WebSocket连接或Server端断掉连接前,不需要客户端和服务端重新发起连接请求。

在海量并发和客户端与服务器交互负载流量大的情况下,极大的节省了网络带宽资源的消耗,有明显的性能优势,且客户端发送和接受消息是在同一个持久连接上发起,实时性优势明显。

程序员转行学什么语言?

https://edu.csdn.net/topic/ai30?utm_source=csdn_bw

接下来我看下websocket如何实现客户端与服务端双向通信:

// websocket.html
<div id="clock"></div>
<script>
let clockDiv = document.getElementById('clock')
let socket = new WebSocket('ws://localhost:9999')
//当连接成功之后就会执行回调函数
socket.onopen = function(){
  console.log('客户端连接成功')
  //再向服务 器发送一个消息
  socket.send('hello'//客户端发的消息内容 为hello
}
//绑定事件是用加属性的方式
socket.onmessage = function(event){
  clockDiv.innerHTML = event.data
  console.log('收到服务器端的响应', event.data)
}
</script>

// websocket.js
let express = require('express')
let app = express()
app.use(express.static(__dirname))
//http服务器
app.listen(3000)
let WebSocketServer = require('ws').Server
//用ws模块启动一个websocket服务器,监听了9999端口
let wsServer = new WebSocketServer({ port9999 })
//监听客户端的连接请求  当客户端连接服务器的时候,就会触发connection事件
//socket代表一个客户端,不是所有客户端共享的,而是每个客户端都有一个socket
wsServer.on('connection'function(socket){
  //每一个socket都有一个唯一的ID属性
  console.log(socket)
  console.log('客户端连接成功')
  //监听对方发过来的消息
  socket.on('message'function(message){
    console.log('接收到客户端的消息', message)
    socket.send('服务器回应:' + message)
  })
})

启动本地服务,打开http://localhost:3000/websocket.html,得到如下结果:

Web 实时推送技术的比较

综上所述:Websocket协议不仅解决了HTTP协议中服务端的被动性,即通信只能由客户端发起,也解决了数据同步有延迟的问题,同时还带来了明显的性能优势,所以websocket是Web实时推送技术的比较理想的方案,但如果要兼容低版本浏览器,可以考虑用轮询来实现。

作者简介:浪里行舟,硕士研究生,专注于前端,运营有个人公众号:前端工匠,致力于打造适合初中级工程师能够快速吸收的一系列优质文章。

声明:本文为CSDN技术头条专栏原创投稿,未经允许请勿转载。欢迎大家通过以下方式联系投稿。

文章广告为微信自动匹配,与本平台无关,如遇假冒伪劣请联系微信进行举报。

【End】

 热 文 推 荐 

华为 5G 欧洲崛起!

☞Google 纪念万维网 30 年:没有 HTTP 协议就没有互联网

☞近 45 亿元拿下开源服务器 Nginx,F5 买断应用交付未来?

16 岁程序媛遭辍学歧视死亡威胁,最终是如何开发出爆款应用的?

13 岁女学生因两行 JavaScript 代码被捕!

☞中国区块链开发者真实现状:半数只懂皮毛; 数据分析师吃香; Java/Python或成为主流开发语言

☞波音737连续坠毁,AI要背锅?

☞人人之间“不简单”,关系图谱“有一套”

☞没有一个人,能躲过程序员的诱惑!

System.out.println("点个好看吧!");
console.log("点个好看吧!");
print("点个好看吧!");
printf("点个好看吧!\n");
cout << "点个好看吧!" << endl;
Console.WriteLine("点个好看吧!");
Response.Write("点个好看吧!");
alert("点个好看吧!")
echo "点个好看吧!"

点击阅读原文,输入关键词,即可搜索您想要的 CSDN 文章。

喜欢就点击“好看”吧!

Web 实时推送技术如何弥补 HTTP 协议的缺陷? | 技术头条相关推荐

  1. WEB 实时推送技术总结

    前言 随着 Web 的发展,用户对于 Web 的实时推送要求也越来越高 ,比如,工业运行监控.Web 在线通讯.即时报价系统.在线游戏等,都需要将后台发生的变化主动地.实时地传送到浏览器端,而不需要用 ...

  2. Web 实时推送技术的总结

    前言 随着 Web 的发展,用户对于 Web 的实时推送要求也越来越高 ,比如,工业运行监控.Web 在线通讯.即时报价系统.在线游戏等,都需要将后台发生的变化主动地.实时地传送到浏览器端,而不需要用 ...

  3. html页面推送功能的实现,想实现Web页面内容自动更新?你需要了解WEB实时推送技术!...

    随着 Web 的发展,用户对于 Web 的实时推送要求也越来越高 ,比如,工业运行监控.Web 在线通讯.即时报价系统.在线游戏等,都需要将后台发生的变化主动地.实时地传送到浏览器端,而不需要用户手动 ...

  4. 终于实现Web实时推送啦!

    需要完成的需求: 定时推送一条消息到客户端,如果用户接收到了该条消息则给服务器一个反馈.且显示每条消息的到达率. 用到的第三方服务: GoEasy推送 JAVA Web实时消息后台服务器推送技术 实现 ...

  5. 关于 Web消息推送系统 web-msg-sender 配置https 协议

    前几天做了一个语音播报功能,本地测试ok,但是上线要求https协议费了点时间 1.启动失败情况出现如下错误 Waring stream_socket_server has been disabled ...

  6. WEB消息推送—GoEasy

    web实时推送的技术在大多数项目里面都会用到,尤其是一些实时性要求高的项目,关于这方面的实现技术有许多,类似于webscoket.dwr.comet4j和netpush等等,其中在以往的篇幅里我也介绍 ...

  7. php消息实时推送技术,基于HTTP协议之WEB消息实时推送技术原理及实现

    很早就想写一些关于网页消息实时推送技术方面的文章,但是由于最近实在忙,没有时间去写文章.本文主要讲解基于 HTTP1.1 协议的 WEB 推送的技术原理及实现.本人曾经在工作的时候也有做过一些用到网页 ...

  8. web服务器推送技术

    传统模式的 Web 系统以客户端发出请求.服务器端响应的方式工作.不能满足很多现实应用的需求,譬如: 监控系统:后台硬件温度.电压发生变化: 即时通信系统:其它用户登录.发送信息: 即时报价系统:后台 ...

  9. Azure SignaIR 将数据从服务器实时推送到Web 和移动浏览器、桌面应用、移动应用等客户端

    本文章完整免费视频讲解地址: Azure SignaIR-向各种客户端实时推送 常规的推送技术:Websocket /服务器发送事件 (SSE) /长轮询等其他技术. ​ SignaIR存在了很长的历 ...

最新文章

  1. LeetCode每日一题 141. 环形链表
  2. 若非必要请勿直接使用@_
  3. 用Shell脚本在推出的RAC节点上批量部署32个Oracle11gR2 RAC备份恢复案例场景的方法PART2...
  4. 工作112:空字符串引发的问题
  5. 浅析 Linux 初始化 init 系统,第 2 部分: UpStart
  6. 设计模式在项目中的应用案例_项目化学习案例(五):菊花种植的秘密——项目化学习在菊种植课程中的应用设计案例...
  7. S2011打印机的IP设置
  8. 东华大学计算机学院刘国华,计算机科学与技术学院2016级迎新大会顺利举行
  9. 计算机操作系统详细学习笔记(一):计算机操作系统概述
  10. https默认端口_Java企业信息化平台O2OA如何配置服务器来启用HTTPS(SSL)
  11. 01.Unity设置成为中文
  12. 阅读圣经丨变量引起的上下文
  13. Zuken CADSTAR 16 破解过程
  14. 海康摄像头拍照(java版,拿走即用)
  15. HTL5 JavaScript里的DOM节点简单思维导图(元素节点,文本节点,节点的增删改查) 高清可打印
  16. php dingo和jwt,DingoApi 中使用 JWT
  17. 微信电子健康卡开放平台接口对接
  18. python爬虫:用无头浏览器selenium爬取taptap游戏榜单并保存为csv
  19. 黑马程序员——结缘黑马
  20. 解决:谷歌浏览器下载链接时一闪一闪的问题

热门文章

  1. mysql存储过程灌数据_【mysql实战】存储过程灌入一百万数据
  2. 如何在矩池云GPU云中安装MATLAB R2017b软件
  3. python捕捉warning_python – 如何格式化logging.captureWarnings捕获的警告?
  4. 目标检测数据集制作常用脚本集合
  5. ubuntu误删旧内核,重启后循环检测进不了系统解决方案
  6. 《统计学习方法》—— 朴素贝叶斯方法、详细推导及其python3实现(一)
  7. 封装jQuery Validate扩展验证方法
  8. android support v4 viewstub,Android 控件ViewStub
  9. linux线程调度与rtos,实时Linux和RTOS的基本特性及技术进行比较
  10. V 神呼吁宽大处理,以太坊开发者 Virgil Griffith 被判入狱 63 个月