国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項超值服

開通VIP
Web 實(shí)時推送技術(shù)如何彌補(bǔ) HTTP 協(xié)議的缺陷? | 技術(shù)頭條

隨著 Web 的發(fā)展,用戶對于 Web 的實(shí)時推送要求也越來越高 ,比如,工業(yè)運(yùn)行監(jiān)控、Web 在線通訊、即時報價系統(tǒng)、在線游戲等,都需要將后臺發(fā)生的變化主動地、實(shí)時地傳送到瀏覽器端,而不需要用戶手動地刷新頁面。本文對過去和現(xiàn)在流行的 Web 實(shí)時推送技術(shù)進(jìn)行了比較與總結(jié)。

紙上得來終覺淺,建議大家動手敲敲代碼——本文完整的源代碼請猛戳Github博客(https://github.com/ljianshu/Blog)。

雙向通信

HTTP 協(xié)議有一個缺陷:通信只能由客戶端發(fā)起。舉例來說,我們想了解今天的天氣,只能是客戶端向服務(wù)器發(fā)出請求,服務(wù)器返回查詢結(jié)果,HTTP 協(xié)議做不到服務(wù)器主動向客戶端推送信息。這種單向請求的特點(diǎn),注定了如果服務(wù)器有連續(xù)的狀態(tài)變化,客戶端要獲知就非常麻煩。

在WebSocket協(xié)議之前,有三種實(shí)現(xiàn)雙向通信的方式:輪詢(polling)、長輪詢(long-polling)和iframe流(streaming)。

1.輪詢(polling)

 

輪詢是客戶端和服務(wù)器之間會一直進(jìn)行連接,每隔一段時間就詢問一次。其缺點(diǎn)也很明顯:連接數(shù)會很多,一個接受,一個發(fā)送。而且每次發(fā)送請求都會有Http的Header,會很耗流量,也會消耗CPU的利用率。 

  • 優(yōu)點(diǎn):實(shí)現(xiàn)簡單,無需做過多的更改;

  • 缺點(diǎn):輪詢的間隔過長,會導(dǎo)致用戶不能及時接收到更新的數(shù)據(jù);輪詢的間隔過短,會導(dǎo)致查詢請求過多,增加服務(wù)器端的負(fù)擔(dān)。

// 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>

//輪詢  服務(wù)端
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);

啟動本地服務(wù),打開http://localhost:8080/1.html,得到如下結(jié)果:

 

2.長輪詢(long-polling)

 

長輪詢是對輪詢的改進(jìn)版,客戶端發(fā)送HTTP給服務(wù)器之后,看有沒有新消息,如果沒有新消息,就一直等待。當(dāng)有新消息的時候,才會返回給客戶端。在某種程度上減小了網(wǎng)絡(luò)帶寬和CPU利用率等問題。由于http數(shù)據(jù)包的頭部數(shù)據(jù)量往往很大(通常有400多個字節(jié)),但是真正被服務(wù)器需要的數(shù)據(jù)卻很少(有時只有10個字節(jié)左右),這樣的數(shù)據(jù)包在網(wǎng)絡(luò)上周期性的傳輸,難免對網(wǎng)絡(luò)帶寬是一種浪費(fèi)。

  • 優(yōu)點(diǎn):比 Polling 做了優(yōu)化,有較好的時效性;

  • 缺點(diǎn):保持連接會消耗資源;服務(wù)器沒有返回有效數(shù)據(jù),程序超時。

// 2.html  服務(wù)端代碼同上
<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) {
        //如果返回成功了,則顯示結(jié)果
        clockDiv.innerHTML = xhr.responseText
      }
      send() //不管成功還是失敗都會發(fā)下一次請求
    }
  }
  xhr.ontimeout = function() {
    send()
  }
  xhr.send()
}
send()
</script>

3.iframe流(streaming)

 

iframe流方式是在頁面中插入一個隱藏的iframe,利用其src屬性在服務(wù)器和客戶端之間創(chuàng)建一條長連接,服務(wù)器向iframe傳輸數(shù)據(jù)(通常是HTML,內(nèi)有負(fù)責(zé)插入信息的javascript),來實(shí)時更新頁面。

  • 優(yōu)點(diǎn):消息能夠?qū)崟r到達(dá);瀏覽器兼容好;

  • 缺點(diǎn):服務(wù)器維護(hù)一個長連接會增加開銷;IE、chrome、Firefox會顯示加載沒有完成,圖標(biāo)會不停旋轉(zhuǎn)。

// 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)

啟動本地服務(wù),打開http://localhost:8080/3.html,得到如下結(jié)果: 

上述代碼中,客戶端只請求一次,然而服務(wù)端卻是源源不斷向客戶端發(fā)送數(shù)據(jù),這樣服務(wù)器維護(hù)一個長連接會增加開銷。

以上我們介紹了三種實(shí)時推送技術(shù),然而各自的缺點(diǎn)很明顯,使用起來并不理想,接下來我們著重介紹另一種技術(shù)——websocket,它是比較理想的雙向通信技術(shù)。

WebSocket

1.什么是websocket?

WebSocket是一種全新的協(xié)議,隨著HTML5草案的不斷完善,越來越多的現(xiàn)代瀏覽器開始全面支持WebSocket技術(shù)了,它將TCP的Socket(套接字)應(yīng)用在了webpage上,從而使通信雙方建立起一個保持在活動狀態(tài)連接通道。

一旦Web服務(wù)器與客戶端之間建立起WebSocket協(xié)議的通信連接,之后所有的通信都依靠這個專用協(xié)議進(jìn)行。通信過程中可互相發(fā)送JSON、XML、HTML或圖片等任意格式的數(shù)據(jù)。由于是建立在HTTP基礎(chǔ)上的協(xié)議,因此連接的發(fā)起方仍是客戶端,而一旦確立WebSocket通信連接,不論服務(wù)器還是客戶端,任意一方都可直接向?qū)Ψ桨l(fā)送報文。

初次接觸 WebSocket 的人,都會問同樣的問題:我們已經(jīng)有了 HTTP 協(xié)議,為什么還需要另一個協(xié)議?

2.HTTP的局限性

HTTP是半雙工協(xié)議,也就是說,在同一時刻數(shù)據(jù)只能單向流動,客戶端向服務(wù)器發(fā)送請求(單向的),然后服務(wù)器響應(yīng)請求(單向的)。

服務(wù)器不能主動推送數(shù)據(jù)給瀏覽器。這就會導(dǎo)致一些高級功能難以實(shí)現(xiàn),諸如聊天室場景就沒法實(shí)現(xiàn)。

3.WebSocket的特點(diǎn)

  • 支持雙向通信,實(shí)時性更強(qiáng);

  • 可以發(fā)送文本,也可以發(fā)送二進(jìn)制數(shù)據(jù);

  • 減少通信量:只要建立起WebSocket連接,就希望一直保持連接狀態(tài)。和HTTP相比,不但每次連接時的總開銷減少,而且由于WebSocket的首部信息很小,通信量也相應(yīng)減少了。

 

相對于傳統(tǒng)的HTTP每次請求-應(yīng)答都需要客戶端與服務(wù)端建立連接的模式,WebSocket是類似Socket的TCP長連接的通訊模式,一旦WebSocket連接建立后,后續(xù)數(shù)據(jù)都以幀序列的形式傳輸。

在客戶端斷開WebSocket連接或Server端斷掉連接前,不需要客戶端和服務(wù)端重新發(fā)起連接請求。

在海量并發(fā)和客戶端與服務(wù)器交互負(fù)載流量大的情況下,極大的節(jié)省了網(wǎng)絡(luò)帶寬資源的消耗,有明顯的性能優(yōu)勢,且客戶端發(fā)送和接受消息是在同一個持久連接上發(fā)起,實(shí)時性優(yōu)勢明顯。

接下來我看下websocket如何實(shí)現(xiàn)客戶端與服務(wù)端雙向通信:

// websocket.html
<div id='clock'></div>
<script>
let clockDiv = document.getElementById('clock')
let socket = new WebSocket('ws://localhost:9999')
//當(dāng)連接成功之后就會執(zhí)行回調(diào)函數(shù)
socket.onopen = function() {
  console.log('客戶端連接成功')
  //再向服務(wù) 器發(fā)送一個消息
  socket.send('hello'//客戶端發(fā)的消息內(nèi)容 為hello
}
//綁定事件是用加屬性的方式
socket.onmessage = function(event{
  clockDiv.innerHTML = event.data
  console.log('收到服務(wù)器端的響應(yīng)', event.data)
}
</script>

// websocket.js
let express = require('express')
let app = express()
app.use(express.static(__dirname))
//http服務(wù)器
app.listen(3000)
let WebSocketServer = require('ws').Server
//用ws模塊啟動一個websocket服務(wù)器,監(jiān)聽了9999端口
let wsServer = new WebSocketServer({ port9999 })
//監(jiān)聽客戶端的連接請求  當(dāng)客戶端連接服務(wù)器的時候,就會觸發(fā)connection事件
//socket代表一個客戶端,不是所有客戶端共享的,而是每個客戶端都有一個socket
wsServer.on('connection'function(socket{
  //每一個socket都有一個唯一的ID屬性
  console.log(socket)
  console.log('客戶端連接成功')
  //監(jiān)聽對方發(fā)過來的消息
  socket.on('message'function(message{
    console.log('接收到客戶端的消息', message)
    socket.send('服務(wù)器回應(yīng):' + message)
  })
})

啟動本地服務(wù),打開http://localhost:3000/websocket.html,得到如下結(jié)果: 

 

Web 實(shí)時推送技術(shù)的比較

綜上所述:Websocket協(xié)議不僅解決了HTTP協(xié)議中服務(wù)端的被動性,即通信只能由客戶端發(fā)起,也解決了數(shù)據(jù)同步有延遲的問題,同時還帶來了明顯的性能優(yōu)勢,所以websocket是Web實(shí)時推送技術(shù)的比較理想的方案,但如果要兼容低版本瀏覽器,可以考慮用輪詢來實(shí)現(xiàn)。

作者簡介:浪里行舟,碩士研究生,專注于前端,運(yùn)營有個人公眾號:前端工匠,致力于打造適合初中級工程師能夠快速吸收的一系列優(yōu)質(zhì)文章。

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
由淺入深學(xué)習(xí)long polling(反向Ajax, Comet)
搭建即時通訊服務(wù)器WebSocket,挺容易嘛
初識webSocket及其使用
九種跨域方式實(shí)現(xiàn)原理
HTML5 通信API 跨域門檻將不再高、數(shù)據(jù)推送也不再是夢
Comet (Web技術(shù))
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服