Web 实时推送技术如何弥补 HTTP 协议的缺陷? | 技术头条
作者 | 浪里行舟
责编 | 郭芮
人工智能的现状及今后发展趋势如何?
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({ port: 9999 })
//监听客户端的连接请求 当客户端连接服务器的时候,就会触发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 协议的缺陷? | 技术头条相关推荐
- WEB 实时推送技术总结
前言 随着 Web 的发展,用户对于 Web 的实时推送要求也越来越高 ,比如,工业运行监控.Web 在线通讯.即时报价系统.在线游戏等,都需要将后台发生的变化主动地.实时地传送到浏览器端,而不需要用 ...
- Web 实时推送技术的总结
前言 随着 Web 的发展,用户对于 Web 的实时推送要求也越来越高 ,比如,工业运行监控.Web 在线通讯.即时报价系统.在线游戏等,都需要将后台发生的变化主动地.实时地传送到浏览器端,而不需要用 ...
- html页面推送功能的实现,想实现Web页面内容自动更新?你需要了解WEB实时推送技术!...
随着 Web 的发展,用户对于 Web 的实时推送要求也越来越高 ,比如,工业运行监控.Web 在线通讯.即时报价系统.在线游戏等,都需要将后台发生的变化主动地.实时地传送到浏览器端,而不需要用户手动 ...
- 终于实现Web实时推送啦!
需要完成的需求: 定时推送一条消息到客户端,如果用户接收到了该条消息则给服务器一个反馈.且显示每条消息的到达率. 用到的第三方服务: GoEasy推送 JAVA Web实时消息后台服务器推送技术 实现 ...
- 关于 Web消息推送系统 web-msg-sender 配置https 协议
前几天做了一个语音播报功能,本地测试ok,但是上线要求https协议费了点时间 1.启动失败情况出现如下错误 Waring stream_socket_server has been disabled ...
- WEB消息推送—GoEasy
web实时推送的技术在大多数项目里面都会用到,尤其是一些实时性要求高的项目,关于这方面的实现技术有许多,类似于webscoket.dwr.comet4j和netpush等等,其中在以往的篇幅里我也介绍 ...
- php消息实时推送技术,基于HTTP协议之WEB消息实时推送技术原理及实现
很早就想写一些关于网页消息实时推送技术方面的文章,但是由于最近实在忙,没有时间去写文章.本文主要讲解基于 HTTP1.1 协议的 WEB 推送的技术原理及实现.本人曾经在工作的时候也有做过一些用到网页 ...
- web服务器推送技术
传统模式的 Web 系统以客户端发出请求.服务器端响应的方式工作.不能满足很多现实应用的需求,譬如: 监控系统:后台硬件温度.电压发生变化: 即时通信系统:其它用户登录.发送信息: 即时报价系统:后台 ...
- Azure SignaIR 将数据从服务器实时推送到Web 和移动浏览器、桌面应用、移动应用等客户端
本文章完整免费视频讲解地址: Azure SignaIR-向各种客户端实时推送 常规的推送技术:Websocket /服务器发送事件 (SSE) /长轮询等其他技术. SignaIR存在了很长的历 ...
最新文章
- LeetCode每日一题 141. 环形链表
- 若非必要请勿直接使用@_
- 用Shell脚本在推出的RAC节点上批量部署32个Oracle11gR2 RAC备份恢复案例场景的方法PART2...
- 工作112:空字符串引发的问题
- 浅析 Linux 初始化 init 系统,第 2 部分: UpStart
- 设计模式在项目中的应用案例_项目化学习案例(五):菊花种植的秘密——项目化学习在菊种植课程中的应用设计案例...
- S2011打印机的IP设置
- 东华大学计算机学院刘国华,计算机科学与技术学院2016级迎新大会顺利举行
- 计算机操作系统详细学习笔记(一):计算机操作系统概述
- https默认端口_Java企业信息化平台O2OA如何配置服务器来启用HTTPS(SSL)
- 01.Unity设置成为中文
- 阅读圣经丨变量引起的上下文
- Zuken CADSTAR 16 破解过程
- 海康摄像头拍照(java版,拿走即用)
- HTL5 JavaScript里的DOM节点简单思维导图(元素节点,文本节点,节点的增删改查) 高清可打印
- php dingo和jwt,DingoApi 中使用 JWT
- 微信电子健康卡开放平台接口对接
- python爬虫:用无头浏览器selenium爬取taptap游戏榜单并保存为csv
- 黑马程序员——结缘黑马
- 解决:谷歌浏览器下载链接时一闪一闪的问题
热门文章
- mysql存储过程灌数据_【mysql实战】存储过程灌入一百万数据
- 如何在矩池云GPU云中安装MATLAB R2017b软件
- python捕捉warning_python – 如何格式化logging.captureWarnings捕获的警告?
- 目标检测数据集制作常用脚本集合
- ubuntu误删旧内核,重启后循环检测进不了系统解决方案
- 《统计学习方法》—— 朴素贝叶斯方法、详细推导及其python3实现(一)
- 封装jQuery Validate扩展验证方法
- android support v4 viewstub,Android 控件ViewStub
- linux线程调度与rtos,实时Linux和RTOS的基本特性及技术进行比较
- V 神呼吁宽大处理,以太坊开发者 Virgil Griffith 被判入狱 63 个月