连接上进行全双工通讯的协议,用户对于 Web 的实时推送要求也越来越高

  • 栏目:基础 时间:2020-04-05 22:28
<返回列表

WebSocket(WS)是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议,它允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就可以直接创建持久性的连接,并进行双向数据传输。

时间: 2018-09-12阅读: 343标签: 推送前言

通常 WebSocket 可用于替换 AJax 技术进行推送,继而实现成本更低、更实时的通讯,一般 WebSocket 也主要用于需要进行实时通信的应用。 

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

日前 Firefox 开发人员在博客中介绍了其将在 Firefox 71 中引入的 WebSocket 检查器。

本文完整的源代码请猛戳Github博客,纸上得来终觉浅,建议大家动手敲敲代码。

新的 WebSocket 检查器是 DevTools 中现有“ 网络”面板 UI 的一部分,在此面板中已经可以过滤已打开的 WS 连接的内容,但是目前仍然不能看到通过 WS 帧传输的实际数据。

一、双向通信

以下屏幕截图显示了运行中的 WS 过滤器,响应代码指示服务器正在切换到 WS 连接。

HTTP 协议有一个缺陷:通信只能由客户端发起。举例来说,我们想了解今天的天气,只能是客户端向服务器发出请求,服务器返回查询结果。HTTP 协议做不到服务器主动向客户端推送信息。这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦。在WebSocket协议之前,有三种实现双向通信的方式:轮询(polling)、长轮询(long-polling)和iframe流(streaming)

图片 1

1.轮询(polling)

如下图所示,边栏显示了有关所选 HTTP 请求的详细信息。此外,UI 现在提供了一个全新的“ 消息”面板,该面板可用于检查通过选定 WS 连接发送和接收的 WS 帧。

轮询是客户端和服务器之间会一直进行连接,每隔一段时间就询问一次。其缺点也很明显:连接数会很多,一个接受,一个发送。而且每次发送请求都会有Http的Header,会很耗流量,也会消耗CPU的利用率

图片 2

优点:实现简单,无需做过多的更改缺点:轮询的间隔过长,会导致用户不能及时接收到更新的数据;轮询的间隔过短,会导致查询请求过多,增加服务器端的负担

实时更新的表显示了已发送(绿色箭头)和已接收(红色箭头)WS 帧的数据,单击时每个帧都会展开,可以检查格式化的数据。

// 1.htmldiv /divscript 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);

专注于特定消息的话,可以将帧过滤为自由文本。

2.长轮询(long-polling)

图片 3

长轮询是对轮询的改进版,客户端发送HTTP给服务器之后,看有没有新消息,如果没有新消息,就一直等待。当有新消息的时候,才会返回给客户端。在某种程度上减小了网络带宽和CPU利用率等问题。由于http数据包的头部数据量往往很大(通常有400多个字节),但是真正被服务器需要的数据却很少(有时只有10个字节左右),这样的数据包在网络上周期性的传输,难免对网络带宽是一种浪费

默认显示“数据”和“时间”列,但是可以自定义界面查看更多列。

优点:比 Polling 做了优化,有较好的时效性缺点:保持连接会消耗资源; 服务器没有返回有效数据,程序超时。

图片 4

// 2.html 服务端代码同上div /divscriptlet 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)

图片 5

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

该检查器当前支持以下 WS 协议:

优点:消息能够实时到达;浏览器兼容好缺点:服务器维护一个长连接会增加开销;IE、chrome、Firefox会显示加载没有完成,图标会不停旋转。

// 3.htmlbody div /div iframe src="/clock" /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)

新的 WS 检查器将解析基于这些协议的有效负载并将其显示为可扩展树,以便于检查。当然,仍然可以查看原始数据:

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

图片 6

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

使用“网络”面板工具栏中的“暂停/继续”按钮可以停止拦截 WS 通信,方便仅捕获感兴趣的帧。

二、WebSocket1.什么是websocket

图片 7

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

WebSocket 检查器将在 Firefox 71 中发布,现在可以在 Firefox Developer Edition 中使用。目前 Firefox 还在对以下功能进行跟进:

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

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

详情查看原博客:

2.HTTP的局限性HTTP是半双工协议,也就是说,在同一时刻数据只能单向流动,客户端向服务器发送请求(单向的),然后服务器响应请求(单向的)。服务器不能主动推送数据给浏览器。这就会导致一些高级功能难以实现,诸如聊天室场景就没法实现。3.WebSocket的特点支持双向通信,实时性更强可以发送文本,也可以发送二进制数据减少通信量:只要建立起WebSocket连接,就希望一直保持连接状态。和HTTP相比,不但每次连接时的总开销减少,而且由于WebSocket的首部信息很小,通信量也相应减少了

https://hacks.mozilla.org/2019/10/firefoxs-new-websocket-inspector

相对于传统的HTTP每次请求-应答都需要客户端与服务端建立连接的模式,WebSocket是类似Socket的TCP长连接的通讯模式,一旦WebSocket连接建立后,后续数据都以帧序列的形式传输。在客户端断开WebSocket连接或Server端断掉连接前,不需要客户端和服务端重新发起连接请求。在海量并发和客户端与服务器交互负载流量大的情况下,极大的节省了网络带宽资源的消耗,有明显的性能优势,且客户端发送和接受消息是在同一个持久连接上发起,实时性优势明显

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

// websocket.htmldiv /divscriptlet 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.jslet 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代表一个客户端,不是所有客户端共享的,而是每个客户端都有一个socketwsServer.on('connection', function(socket) { //每一个socket都有一个唯一的ID属性 console.log(socket) console.log('客户端连接成功') //监听对方发过来的消息 socket.on('message', function(message) { console.log('接收到客户端的消息', message) socket.send('服务器回应:' + message) })})

三、Web 实时推送技术的比较

方式

类型

技术实现

优点

缺点

适用场景

轮询Pollingclient→server客户端循环请求1、实现简单 2、 支持跨域1、浪费带宽和服务器资源 2、 一次请求信息大半是无用(完整http头信息) 3、有延迟 4、大部分无效请求适于小型应用长轮询Long-Pollingclient→server服务器hold住连接,一直到有数据或者超时才返回,减少重复请求次数1、实现简单 2、不会频繁发请求 3、节省流量 4、延迟低1、服务器hold住连接,会消耗资源 2、一次请求信息大半是无用WebQQ、Hi网页版、Facebook IM长连接iframeclient→server在页面里嵌入一个隐蔵iframe,将这个 iframe 的 src 属性设为对一个长连接的请求,服务器端就能源源不断地往客户端输入数据。1、数据实时送达 2、不发无用请求,一次链接,多次“推送”1、服务器增加开销 2、无法准确知道连接状态 3、IE、chrome等一直会处于loading状态Gmail聊天WebSocketserver⇌clientnew WebSocket()1、支持双向通信,实时性更强 2、可发送二进制文件3、减少通信量1、浏览器支持程度不一致 2、不支持断开重连网络游戏、银行交互和支付

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

上一篇:Go语言为何不受待见 下一篇:没有了

更多阅读

连接上进行全双工通讯的协议,用户对于

基础 2020-04-05
WebSocket(WS)是 HTML5 开始提供的一种在单个 TCP连接上进行全双工通讯的协议,它允许服务端主...
查看全文

一个新的开源指令集架构RISC-V在芯片江湖

基础 2020-04-05
“开源”一词所代表的不仅仅是技术人员的情怀,它还传达了诸如研究知识共享和社区建设之...
查看全文

项目也正是采用 Rust 编写,以及其他编程

基础 2020-04-05
毫无疑问,Rust 目前发展势头正劲。此前,微软安全响应中心探索采用 Rust的消息引发大量关注...
查看全文

友情链接: 网站地图

Copyright © 2015-2019 http://www.koi-bumi.com. 韦德体育有限公司 版权所有