摘要:本文對(duì)過(guò)去和現(xiàn)在流行的實(shí)時(shí)推送技術(shù)進(jìn)行了比較與總結(jié)。以上我們介紹了三種實(shí)時(shí)推送技術(shù),然而各自的缺點(diǎn)很明顯,使用起來(lái)并不理想,接下來(lái)我們著重介紹另一種技術(shù)它是比較理想的雙向通信技術(shù)。
前言
隨著 Web 的發(fā)展,用戶(hù)對(duì)于 Web 的實(shí)時(shí)推送要求也越來(lái)越高 ,比如,工業(yè)運(yùn)行監(jiān)控、Web 在線通訊、即時(shí)報(bào)價(jià)系統(tǒng)、在線游戲等,都需要將后臺(tái)發(fā)生的變化主動(dòng)地、實(shí)時(shí)地傳送到瀏覽器端,而不需要用戶(hù)手動(dòng)地刷新頁(yè)面。本文對(duì)過(guò)去和現(xiàn)在流行的 Web 實(shí)時(shí)推送技術(shù)進(jìn)行了比較與總結(jié)。
本文完整的源代碼請(qǐng)猛戳Github博客,紙上得來(lái)終覺(jué)淺,建議大家動(dòng)手敲敲代碼。
一、雙向通信HTTP 協(xié)議有一個(gè)缺陷:通信只能由客戶(hù)端發(fā)起。舉例來(lái)說(shuō),我們想了解今天的天氣,只能是客戶(hù)端向服務(wù)器發(fā)出請(qǐng)求,服務(wù)器返回查詢(xún)結(jié)果。HTTP 協(xié)議做不到服務(wù)器主動(dòng)向客戶(hù)端推送信息。這種單向請(qǐng)求的特點(diǎn),注定了如果服務(wù)器有連續(xù)的狀態(tài)變化,客戶(hù)端要獲知就非常麻煩。在WebSocket協(xié)議之前,有三種實(shí)現(xiàn)雙向通信的方式:輪詢(xún)(polling)、長(zhǎng)輪詢(xún)(long-polling)和iframe流(streaming)。
1.輪詢(xún)(polling)
輪詢(xún)是客戶(hù)端和服務(wù)器之間會(huì)一直進(jìn)行連接,每隔一段時(shí)間就詢(xún)問(wèn)一次。其缺點(diǎn)也很明顯:連接數(shù)會(huì)很多,一個(gè)接受,一個(gè)發(fā)送。而且每次發(fā)送請(qǐng)求都會(huì)有Http的Header,會(huì)很耗流量,也會(huì)消耗CPU的利用率。
優(yōu)點(diǎn):實(shí)現(xiàn)簡(jiǎn)單,無(wú)需做過(guò)多的更改
缺點(diǎn):輪詢(xún)的間隔過(guò)長(zhǎng),會(huì)導(dǎo)致用戶(hù)不能及時(shí)接收到更新的數(shù)據(jù);輪詢(xún)的間隔過(guò)短,會(huì)導(dǎo)致查詢(xún)請(qǐng)求過(guò)多,增加服務(wù)器端的負(fù)擔(dān)
// 1.html
//輪詢(xún) 服務(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);
啟動(dòng)本地服務(wù),打開(kāi)http://localhost:8080/1.html,得到如下結(jié)果:
2.長(zhǎng)輪詢(xún)(long-polling)
長(zhǎng)輪詢(xún)是對(duì)輪詢(xún)的改進(jìn)版,客戶(hù)端發(fā)送HTTP給服務(wù)器之后,看有沒(méi)有新消息,如果沒(méi)有新消息,就一直等待。當(dāng)有新消息的時(shí)候,才會(huì)返回給客戶(hù)端。在某種程度上減小了網(wǎng)絡(luò)帶寬和CPU利用率等問(wèn)題。由于http數(shù)據(jù)包的頭部數(shù)據(jù)量往往很大(通常有400多個(gè)字節(jié)),但是真正被服務(wù)器需要的數(shù)據(jù)卻很少(有時(shí)只有10個(gè)字節(jié)左右),這樣的數(shù)據(jù)包在網(wǎng)絡(luò)上周期性的傳輸,難免對(duì)網(wǎng)絡(luò)帶寬是一種浪費(fèi)。
優(yōu)點(diǎn):比 Polling 做了優(yōu)化,有較好的時(shí)效性
缺點(diǎn):保持連接會(huì)消耗資源; 服務(wù)器沒(méi)有返回有效數(shù)據(jù),程序超時(shí)。
// 2.html 服務(wù)端代碼同上3.iframe流(streaming)
iframe流方式是在頁(yè)面中插入一個(gè)隱藏的iframe,利用其src屬性在服務(wù)器和客戶(hù)端之間創(chuàng)建一條長(zhǎng)連接,服務(wù)器向iframe傳輸數(shù)據(jù)(通常是HTML,內(nèi)有負(fù)責(zé)插入信息的javascript),來(lái)實(shí)時(shí)更新頁(yè)面。
優(yōu)點(diǎn):消息能夠?qū)崟r(shí)到達(dá);瀏覽器兼容好
缺點(diǎn):服務(wù)器維護(hù)一個(gè)長(zhǎng)連接會(huì)增加開(kāi)銷(xiāo);IE、chrome、Firefox會(huì)顯示加載沒(méi)有完成,圖標(biāo)會(huì)不停旋轉(zhuǎn)。
// 3.html
//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(` `) }, 1000) }) app.listen(8080)
啟動(dòng)本地服務(wù),打開(kāi)http://localhost:8080/3.html,得到如下結(jié)果:
上述代碼中,客戶(hù)端只請(qǐng)求一次,然而服務(wù)端卻是源源不斷向客戶(hù)端發(fā)送數(shù)據(jù),這樣服務(wù)器維護(hù)一個(gè)長(zhǎng)連接會(huì)增加開(kāi)銷(xiāo)。
以上我們介紹了三種實(shí)時(shí)推送技術(shù),然而各自的缺點(diǎn)很明顯,使用起來(lái)并不理想,接下來(lái)我們著重介紹另一種技術(shù)--websocket,它是比較理想的雙向通信技術(shù)。
二、WebSocket 1.什么是websocketWebSocket是一種全新的協(xié)議,隨著HTML5草案的不斷完善,越來(lái)越多的現(xiàn)代瀏覽器開(kāi)始全面支持WebSocket技術(shù)了,它將TCP的Socket(套接字)應(yīng)用在了webpage上,從而使通信雙方建立起一個(gè)保持在活動(dòng)狀態(tài)連接通道。
一旦Web服務(wù)器與客戶(hù)端之間建立起WebSocket協(xié)議的通信連接,之后所有的通信都依靠這個(gè)專(zhuān)用協(xié)議進(jìn)行。通信過(guò)程中可互相發(fā)送JSON、XML、HTML或圖片等任意格式的數(shù)據(jù)。由于是建立在HTTP基礎(chǔ)上的協(xié)議,因此連接的發(fā)起方仍是客戶(hù)端,而一旦確立WebSocket通信連接,不論服務(wù)器還是客戶(hù)端,任意一方都可直接向?qū)Ψ桨l(fā)送報(bào)文。
初次接觸 WebSocket 的人,都會(huì)問(wèn)同樣的問(wèn)題:我們已經(jīng)有了 HTTP 協(xié)議,為什么還需要另一個(gè)協(xié)議?
2.HTTP的局限性HTTP是半雙工協(xié)議,也就是說(shuō),在同一時(shí)刻數(shù)據(jù)只能單向流動(dòng),客戶(hù)端向服務(wù)器發(fā)送請(qǐng)求(單向的),然后服務(wù)器響應(yīng)請(qǐng)求(單向的)。
服務(wù)器不能主動(dòng)推送數(shù)據(jù)給瀏覽器。這就會(huì)導(dǎo)致一些高級(jí)功能難以實(shí)現(xiàn),諸如聊天室場(chǎng)景就沒(méi)法實(shí)現(xiàn)。
3.WebSocket的特點(diǎn)支持雙向通信,實(shí)時(shí)性更強(qiáng)
可以發(fā)送文本,也可以發(fā)送二進(jìn)制數(shù)據(jù)
減少通信量:只要建立起WebSocket連接,就希望一直保持連接狀態(tài)。和HTTP相比,不但每次連接時(shí)的總開(kāi)銷(xiāo)減少,而且由于WebSocket的首部信息很小,通信量也相應(yīng)減少了
相對(duì)于傳統(tǒng)的HTTP每次請(qǐng)求-應(yīng)答都需要客戶(hù)端與服務(wù)端建立連接的模式,WebSocket是類(lèi)似Socket的TCP長(zhǎng)連接的通訊模式,一旦WebSocket連接建立后,后續(xù)數(shù)據(jù)都以幀序列的形式傳輸。在客戶(hù)端斷開(kāi)WebSocket連接或Server端斷掉連接前,不需要客戶(hù)端和服務(wù)端重新發(fā)起連接請(qǐng)求。在海量并發(fā)和客戶(hù)端與服務(wù)器交互負(fù)載流量大的情況下,極大的節(jié)省了網(wǎng)絡(luò)帶寬資源的消耗,有明顯的性能優(yōu)勢(shì),且客戶(hù)端發(fā)送和接受消息是在同一個(gè)持久連接上發(fā)起,實(shí)時(shí)性?xún)?yōu)勢(shì)明顯。
接下來(lái)我看下websocket如何實(shí)現(xiàn)客戶(hù)端與服務(wù)端雙向通信:
// websocket.html
// 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模塊啟動(dòng)一個(gè)websocket服務(wù)器,監(jiān)聽(tīng)了9999端口 let wsServer = new WebSocketServer({ port: 9999 }) //監(jiān)聽(tīng)客戶(hù)端的連接請(qǐng)求 當(dāng)客戶(hù)端連接服務(wù)器的時(shí)候,就會(huì)觸發(fā)connection事件 //socket代表一個(gè)客戶(hù)端,不是所有客戶(hù)端共享的,而是每個(gè)客戶(hù)端都有一個(gè)socket wsServer.on("connection", function(socket) { //每一個(gè)socket都有一個(gè)唯一的ID屬性 console.log(socket) console.log("客戶(hù)端連接成功") //監(jiān)聽(tīng)對(duì)方發(fā)過(guò)來(lái)的消息 socket.on("message", function(message) { console.log("接收到客戶(hù)端的消息", message) socket.send("服務(wù)器回應(yīng):" + message) }) })
啟動(dòng)本地服務(wù),打開(kāi)http://localhost:3000/websocket.html,得到如下結(jié)果:
方式 | 類(lèi)型 | 技術(shù)實(shí)現(xiàn) | 優(yōu)點(diǎn) | 缺點(diǎn) | 適用場(chǎng)景 |
---|---|---|---|---|---|
輪詢(xún)Polling | client→server | 客戶(hù)端循環(huán)請(qǐng)求 | 1、實(shí)現(xiàn)簡(jiǎn)單 2、 支持跨域 | 1、浪費(fèi)帶寬和服務(wù)器資源 2、 一次請(qǐng)求信息大半是無(wú)用(完整http頭信息) 3、有延遲 4、大部分無(wú)效請(qǐng)求 | 適于小型應(yīng)用 |
長(zhǎng)輪詢(xún)Long-Polling | client→server | 服務(wù)器hold住連接,一直到有數(shù)據(jù)或者超時(shí)才返回,減少重復(fù)請(qǐng)求次數(shù) | 1、實(shí)現(xiàn)簡(jiǎn)單 2、不會(huì)頻繁發(fā)請(qǐng)求 3、節(jié)省流量 4、延遲低 | 1、服務(wù)器hold住連接,會(huì)消耗資源 2、一次請(qǐng)求信息大半是無(wú)用 | WebQQ、Hi網(wǎng)頁(yè)版、Facebook IM |
長(zhǎng)連接iframe | client→server | 在頁(yè)面里嵌入一個(gè)隱蔵iframe,將這個(gè) iframe 的 src 屬性設(shè)為對(duì)一個(gè)長(zhǎng)連接的請(qǐng)求,服務(wù)器端就能源源不斷地往客戶(hù)端輸入數(shù)據(jù)。 | 1、數(shù)據(jù)實(shí)時(shí)送達(dá) 2、不發(fā)無(wú)用請(qǐng)求,一次鏈接,多次“推送” | 1、服務(wù)器增加開(kāi)銷(xiāo) 2、無(wú)法準(zhǔn)確知道連接狀態(tài) 3、IE、chrome等一直會(huì)處于loading狀態(tài) | Gmail聊天 |
WebSocket | server?client | new WebSocket() | 1、支持雙向通信,實(shí)時(shí)性更強(qiáng) 2、可發(fā)送二進(jìn)制文件3、減少通信量 | 1、瀏覽器支持程度不一致 2、不支持?jǐn)嚅_(kāi)重連 | 網(wǎng)絡(luò)游戲、銀行交互和支付 |
綜上所述:Websocket協(xié)議不僅解決了HTTP協(xié)議中服務(wù)端的被動(dòng)性,即通信只能由客戶(hù)端發(fā)起,也解決了數(shù)據(jù)同步有延遲的問(wèn)題,同時(shí)還帶來(lái)了明顯的性能優(yōu)勢(shì),所以websocket
是Web 實(shí)時(shí)推送技術(shù)的比較理想的方案,但如果要兼容低版本瀏覽器,可以考慮用輪詢(xún)來(lái)實(shí)現(xiàn)。
給大家推薦一個(gè)好用的BUG監(jiān)控工具Fundebug,歡迎免費(fèi)試用!
歡迎關(guān)注公眾號(hào):前端工匠,你的成長(zhǎng)我們一起見(jiàn)證!如果你感覺(jué)有收獲,歡迎給我打賞,以激勵(lì)我更多輸出優(yōu)質(zhì)開(kāi)源內(nèi)容
參考文章WebSocket 教程
珠峰前端架構(gòu)課
Web 實(shí)時(shí)推送技術(shù)的總結(jié)
WebSocket(1): 服務(wù)端“實(shí)時(shí)推送”的演變
長(zhǎng)連接/websocket/SSE等主流服務(wù)器推送技術(shù)比較
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/102507.html
摘要:解決問(wèn)題即時(shí)通信要解決三方面的問(wèn)題雙全工通信低延時(shí)支持跨域各種即時(shí)通信技術(shù)輪詢(xún)客戶(hù)端定時(shí)向服務(wù)器發(fā)送請(qǐng)求,服務(wù)器接到請(qǐng)求后馬上返回響應(yīng)信息并關(guān)閉連接。優(yōu)點(diǎn)實(shí)現(xiàn)真正的即時(shí)通信,而不是偽即時(shí)。 解決問(wèn)題 即時(shí)通信要解決三方面的問(wèn)題: 雙全工通信 低延時(shí) 支持跨域 各種即時(shí)通信技術(shù) 輪詢(xún) 客戶(hù)端定時(shí)向服務(wù)器發(fā)送Ajax請(qǐng)求,服務(wù)器接到請(qǐng)求后馬上返回響應(yīng)信息并關(guān)閉連接。優(yōu)點(diǎn):后端程序編寫(xiě)比...
摘要:輪詢(xún)通過(guò)輪詢(xún),瀏覽器定期發(fā)送請(qǐng)求并立即接收響應(yīng)這項(xiàng)技術(shù)是瀏覽器首次嘗試傳遞實(shí)時(shí)信息。該協(xié)議由兩層組成記錄協(xié)議和握手協(xié)議。安全套接層及其繼任者傳輸層安全,是為網(wǎng)絡(luò)通信提供安全及數(shù)據(jù)完整性的一種安全協(xié)議。移除了開(kāi)銷(xiāo)大幅度減輕了復(fù)雜度。 Web Sockets定義了一種在通過(guò)一個(gè)單一的 socket 在網(wǎng)絡(luò)上進(jìn)行全雙工通訊的通道。它不僅僅是傳統(tǒng)的 HTTP 通訊的一個(gè)增量的提高,尤其對(duì)于實(shí)時(shí)...
摘要:現(xiàn)在已經(jīng)成為的官方標(biāo)準(zhǔn),如,以及的擴(kuò)展協(xié)議。作者簡(jiǎn)介李會(huì)軍,聯(lián)合創(chuàng)始人,關(guān)注團(tuán)隊(duì)協(xié)作領(lǐng)域,致力于用工具解決中小團(tuán)隊(duì)的協(xié)作問(wèn)題。 Worktile自上線兩年多以來(lái),以良好的用戶(hù)體驗(yàn)和穩(wěn)定的服務(wù),獲得了用戶(hù)的認(rèn)可和喜愛(ài)。截止筆者寫(xiě)這篇文章的時(shí)候,已經(jīng)有超過(guò)10萬(wàn)家團(tuán)隊(duì)在使用Worktile。作為團(tuán)隊(duì)協(xié)作工具,從技術(shù)上分析首先要解決如下幾個(gè)問(wèn)題: 基于Web的跨平臺(tái)設(shè)計(jì),讓用戶(hù)在任何地方都...
閱讀 1176·2023-04-26 00:34
閱讀 3347·2023-04-25 16:47
閱讀 2109·2021-11-24 11:14
閱讀 3092·2021-09-26 09:55
閱讀 3682·2019-08-30 15:56
閱讀 3211·2019-08-29 16:57
閱讀 1903·2019-08-26 13:38
閱讀 2662·2019-08-26 12:22