久久国产精品一区二区三区四区,久色婷婷小香蕉久久,国产日韩欧美在线播放不卡,另类av一区二区

天天快報!數據不夠實時:試試長連接?
來源:ELab團隊    時間:2023-01-28 05:55:43
背景

在特定場景下,我們往往需要實時的去獲取最新的數據,如獲取消息推送或公告、聊天消息、實時的日志和學情等,都對數據的實時性要求很高,面對這類場景,最常用的可能就是輪詢,但除了輪詢還有長連接(Websocket)和服務端推送(SSE)方案可供選擇。

輪詢

輪詢就是采用循環http請求的方式,通過重復的接口請求去獲取最新的數據。

短輪詢(polling)

短輪詢可能是我們用的最多的一種實時刷新數據的方式了,我們在講輪詢方案時,大部分指的就是短輪詢,其實現方式和普通的接口無異,改造也只要前端增加定時器或useRequest配置輪詢參數即可,其原理也非常簡單,如下圖,如果是http1.1及以上,TCP連接可以復用,當然http1.0及以下也是可以使用,但消耗會更多。短輪詢的特點就是接口請求立即會返回,每次請求都可以理解為是一次新的請求。


(資料圖片)

短輪詢的優缺點

短輪詢最大的優點就是簡單,前端設置時間間隔,定時去請求數據,而服務端只需同步的查詢數據返回即可,但缺點也顯而易見:

無用請求過多:從下圖可以看出,每隔固定時間,一定有請求發出,且每次接口可能返回一樣的數據或返回空結果,服務端會重復查詢數據庫、前端會重復重渲染實時性不可控,如數據更新了,但輪詢請求剛結束一輪,會造成輪詢間隔內數據都得不到更新長輪詢(long polling)

看完了上面關于短輪詢的介紹,我們知道了輪詢有兩個主要的缺陷:一個是無用請求過多,另外一個是數據實時性不可控。為了解決這兩個問題,于是有了更進一步的長輪詢方案。

在上圖中,客戶端發起請求后,服務端發現當前沒有新的數據,這個時候服務端沒有立即返回請求,而是將請求掛起,在等待一段時間后(一般為30s或者是60s,設置一個超時返回主要是為了考慮過長的無數據連接占用會被網關或者某層中間件斷開甚至是被運營商斷開),如發現還是沒有數據更新的話,就返回一個空結果給客戶端??蛻舳嗽谑盏椒斩说幕貜秃?,立即再次向服務端發送新的請求。這次服務端在接收到客戶端的請求后,同樣等待了一段時間,這次好運的是服務端的數據發生了更新,服務端給客戶端返回了最新的數據??蛻舳嗽谀玫浇Y果后再次發送下一個請求,如此反復。

長輪詢的優缺點

長輪詢很完美地解決了短輪詢的問題,首先服務端在沒有數據更新的情況下沒有給客戶端返回數據,所以避免了客戶端大量的重復請求。再者客戶端在收到服務端的返回后,馬上發送下一個請求,這就保證了更好的數據實時性。不過長輪詢也有缺點:

服務端資源大量消耗: 服務端會一直hold住客戶端的請求,這部分請求會占用服務器的資源。對于某些語言來說,每一個HTTP連接都是一個獨立的線程,過多的HTTP連接會消耗掉服務端的內存資源。難以處理數據更新頻繁的情況: 如果數據更新頻繁,會有大量的連接創建和重建過程,這部分消耗是很大的。雖然HTTP有TCP連接復用,但每次拿到數據后客戶端都需要重新請求,因此相對于WebSocket和SSE它多了一個發送新請求的階段,對實時性和性能還是有影響的。

從上面的描述來看,長輪詢的次數和時延似乎可以更少,那是不是長輪詢更好呢?其實不是的,這個兩種輪詢方式都有優劣勢和適合的場景。

短輪詢,長輪詢怎么選?

長輪詢多用于操作頻繁,點對點的通訊,而且連接數不能太多情況,每個TCP連接都需要三步握手,這需要時間,如果每個操作都是先連接,再操作的話那么處理速度會降低很多,所以每個操作完后都不斷開,次處理時直接發送數據包就OK了,不用建立TCP連接。例如:數據庫的連接用長連接, 如果用短連接頻繁的通信會造成socket錯誤,而且頻繁的socket 創建也是對資源的浪費。

而像WEB網站的http服務一般都用短輪詢,因為長連接對于服務端來說會耗費一定的資源,而像WEB網站這么頻繁的成千上萬甚至上億客戶端的連接用短連接會更省一些資源,如果用長連接,而且同時有成千上萬的用戶,如果每個用戶都占用一個連接的話,那可想而知吧。所以并發量大,但每個用戶無需頻繁操作情況下需用短連好。

長連接?WebSocket?

上面說到長輪詢不適用于服務端資源頻繁更新的場景,而解決這類問題的一個方案就是WebSocket。用最簡單的話來介紹WebSocket就是:客戶端和服務器之間建立一個持久的長連接,這個連接是雙工的,客戶端和服務端都可以實時地給對方發送消息。下面是WebSocket的圖示:

WebSocket對于前端的同學來說是非常常見了,因為無論是webpack還是vite,用來HMR的reload就是通過WebSocket來進行的,有代碼改動,工程重新編譯,新變更的模塊通知到瀏覽器加載新的模塊,這里的通知瀏覽器加載新模塊就是通過WebSocket的進行的。如上圖,通過握手(協議轉換)建立連接后,雙方就保持持久連接,由于歷史的關系,WebSocket建立連接是依賴HTTP的,但是其建連請求有明顯的特征,目的是客戶端和服務端都能識別并保持連接。

請求特征

請求頭特征

HTTP 必須是 1.1 GET 請求HTTP Header 中 Connection 字段的值必須為 UpgradeHTTP Header 中 Upgrade 字段必須為 websocketSec-WebSocket-Key 字段的值是采用 base64 編碼的隨機 16 字節字符串Sec-WebSocket-Protocol 字段的值記錄使用的子協議,比如 binary base64Origin 表示請求來源

響應頭特征

狀態碼是 101 表示 Switching ProtocolsUpgrade / Connection / Sec-WebSocket-Protocol 和請求頭一致Sec-WebSocket-Accept 是通過請求頭的 Sec-WebSocket-Key 生成兼容性

WebSocket 協議在2008年誕生,2011年成為國際標準?,F在所有瀏覽器都已經支持了。

實現一個簡單的WebSocket

基于原生WebSocket我們實現一個簡單的長連。

連接

// 連接只需實例一個WebSocket const ws = new WebSocket(`wss://${url}`);

發送消息

ws.send("這是一條消息:" + count);

監聽消息

ws.onmessage = function (event) { console.log(event.data);}

關閉連接

ws.close();?在工程上使用WebSocket?

在工程上,很少直接基于原生WebSocket實現業務需求,使用WebSocket需要完成下面幾個問題:

鑒權:防止惡意連接連接進來接收消息心跳:客戶端意外斷開,導致死鏈占用服務端資源,長時間無消息的連接可能會被中間網關或運營商斷開登錄:通過建連需要識別出該連接是哪個用戶,有無權限,需要推送哪些消息日志:監控連接,錯誤上報后臺:能方便的查看在線連接的客戶端數量,消息傳輸量服務端推送(SSE)

SSE全稱Server-sent Events,是HTML 5 規范的一個組成部分,該規范十分簡單,主要由兩個部分組成:第一個部分是服務器端與瀏覽器端之間的通訊協議,第二部分則是在瀏覽器端可供 JavaScript 使用的 EventSource 對象。通訊協議是基于純文本的簡單協議。服務器端的響應的內容類型是“text/event-stream”。響應文本的內容可以看成是一個事件流,由不同的事件所組成。每個事件由類型和數據兩部分組成,同時每個事件可以有一個可選的標識符。不同事件的內容之間通過僅包含回車符和換行符的空行(“rn”)來分隔。每個事件的數據可能由多行組成。

?和 Websocket對比?

SSE

WebSocket

單向:僅服務端能發送消息

雙向:客戶端、服務端雙向發送

僅文本數據

二進制、文本都可

常規HTTP協議

WebSocket協議

?兼容性??數據格式?

服務器向瀏覽器發送的 SSE 數據,必須是 UTF-8 編碼的文本,

響應頭

Content-Type: text/event-streamCache-Control: no-cacheConnection: keep-alive數據傳輸

服務端每次發送消息,由若干message?組成,使用\n\n?分隔,如果單個messag?過長,可以用\n分隔。

field取值

dataeventidretry

例子

// 注釋,用于心跳包: this is a test stream\n\n// 設置斷鏈1000ms重試一次retry:1000 \n\nevent: 自定義消息\n\ndata: some text\n\ndata: another message\ndata: with two lines \n\n?實現一個簡單的SSE?web端

實例化EventSource?,監聽open、message、error

const source = new EventSource(url, { withCredentials: true });// 監聽消息source.onmessage = function (event) { // handle message};source.addEventListener("message", function (event) { // handle message}, false);// 監聽錯誤source.onerror = function (event) { // handle error};source.addEventListener("error", function (event) { // handle error}, false);// 關閉連接source.close()服務端

以nodejs為例,服務端代碼和普通請求無異,并沒有新的處理類庫。

res.writeHead(200, { "Content-Type":"text/event-stream", "Cache-Control":"no-cache", "Connection":"keep-alive", "Access-Control-Allow-Origin": "*", }); res.write("retry: 10000\n\n"); res.write("event: connecttime\n\n"); res.write("data: " + (new Date()) + "\n"); res.write("data: " + (new Date()) + "\n\n"); // 模擬收到消息推送給客戶端 interval = setInterval(function () { res.write("data: " + (new Date()) + "\n\n"); }, 1000);

和WebSocket不同,SSE并不是新的通信協議,其本質是在普通HTTP請求的基礎上定義一個Content-Type?,保持上連接,通過普通的接口也能模擬出SSE的效果,以XMLHttpRequest為例

const xhr = new XMLHttpRequest(); xhr.open("GET", "http://localhost:8844/long", true); xhr.onload = (e) => { console.log("onload", xhr.responseText); }; xhr.onprogress = (e) => { // 每次服務端寫入response的數據,都會傳輸過來,并產生一次onprogress事件 console.log("onprogress", xhr.responseText); }; xhr.send();參考文獻

rfc6455.pdf[1]

WebSocket協議中文版(rfc6455)[2]

深入剖析WebSocket的原理 - 知乎[3]

HTTP長連接實現原理 - 掘金[4]

WebSocket() - Web API 接口參考 | MDN[5]

EventSource - Web API 接口參考 | MDN[6]?

關鍵詞: 發送消息 數據更新 服務器端 關閉連接 成千上萬

上一篇:

下一篇:

X 關閉

X 關閉

久久国产精品一区二区三区四区,久色婷婷小香蕉久久,国产日韩欧美在线播放不卡,另类av一区二区
亚洲欧美成aⅴ人在线观看| 欧美在线三级| 日韩一二三区视频| 亚洲欧洲另类| 亚洲精品激情| 亚洲激情在线观看视频免费| 国产综合香蕉五月婷在线| 久久免费国产精品| 久久婷婷影院| 91久久精品视频| 欧美亚洲免费电影| 亚洲视频精选| 久久精品卡一| 99国产精品久久久久久久成人热| 亚洲国产va精品久久久不卡综合| 欧美日韩免费观看中文| 欧美午夜不卡在线观看免费| 欧美主播一区二区三区美女 久久精品人| 国产日韩精品一区二区三区| 久久精品综合| 一本色道久久综合亚洲精品小说| 亚洲免费在线精品一区| 欧美小视频在线| 欧美日韩亚洲一区在线观看| 国产精品视频第一区| 欧美国产激情二区三区| 欧美日韩国产天堂| 老司机67194精品线观看| 亚洲精品视频一区| 欧美激情影院| 免费视频一区| 久热re这里精品视频在线6| 国模精品一区二区三区色天香| 久久久久久婷| 国产九色精品成人porny| 艳女tv在线观看国产一区| 一区二区三区精密机械公司| 欧美成人a∨高清免费观看| 欧美婷婷六月丁香综合色| 欧美国产精品| 亚洲一区免费观看| 欧美专区一区二区三区| 欧美日韩国产美| 久久精品中文字幕一区二区三区| 欧美一区二区三区日韩视频| 亚洲蜜桃精久久久久久久| 亚洲日本中文| 国产精品99久久久久久白浆小说| 国产精品老女人精品视频| 一区二区三区 在线观看视频| 性欧美办公室18xxxxhd| 亚洲三级免费电影| 国产精品私房写真福利视频| 国产亚洲一区在线| 亚洲一区二区三| 欧美三级小说| 亚洲精品国产精品国自产观看| 亚洲福利视频一区二区| 夜夜爽夜夜爽精品视频| 久久精品中文| 欧美精品一区二区蜜臀亚洲| 国产伦理精品不卡| 99精品99久久久久久宅男| 亚洲第一区在线| 亚洲国产第一| 一本一本久久a久久精品综合妖精| 国产一区二区三区四区| 国产一区久久久| 一本色道久久综合狠狠躁的推荐| 亚洲激情一区二区三区| 噜噜噜躁狠狠躁狠狠精品视频| 免费成人在线观看视频| 国内成人精品2018免费看| 蜜桃伊人久久| 亚洲第一狼人社区| 国产真实久久| 欧美激情精品久久久久久变态| 国产精品久久久久天堂| 国语自产精品视频在线看抢先版结局| 欧美大片免费观看| 亚洲午夜一区二区三区| 亚洲欧美日韩另类精品一区二区三区| 欧美一区二区三区免费观看| 国产精品久久久爽爽爽麻豆色哟哟| 久久精品欧美| 亚洲欧洲在线一区| 欧美激情中文不卡| 99v久久综合狠狠综合久久| 国产精品美女久久久免费| 国产视频丨精品|在线观看| 久久一区激情| 国产在线视频欧美一区二区三区| 欧美激情国产高清| 精品96久久久久久中文字幕无| 国产日韩欧美在线看| 一区二区日韩欧美| 久久亚洲综合色一区二区三区| 亚洲黄色有码视频| 欧美成人国产va精品日本一级| 久久综合伊人77777| 国产精品夜夜夜一区二区三区尤| 免费欧美日韩国产三级电影| 免费h精品视频在线播放| 一区二区日韩欧美| 美女诱惑黄网站一区| 国产视频丨精品|在线观看| 亚洲狠狠婷婷| 欧美日韩国产黄| 在线欧美日韩精品| 欧美亚日韩国产aⅴ精品中极品| 狼狼综合久久久久综合网| 黄色欧美日韩| 欧美午夜精彩| 美女爽到呻吟久久久久| 亚洲美女在线观看| 久久久久久久久蜜桃| 亚洲理论在线观看| 亚洲国产精品一区二区www在线| 国产精品久久久91| 亚洲精品国产系列| 最新日韩精品| 欧美a级片网| 久久久亚洲成人| 9l国产精品久久久久麻豆| 欧美日韩亚洲综合一区| 欧美成人免费在线视频| 国语自产偷拍精品视频偷| 国产精品美女诱惑| 国产精品日韩一区| 亚洲国产精品va在线看黑人动漫| 在线视频国产日韩| 久久久久久久999精品视频| 99国产精品久久久久久久成人热| 午夜日韩激情| 国产日韩欧美视频| 欧美亚洲免费高清在线观看| 欧美一区二区三区播放老司机| 精品91久久久久| 欧美日韩国产123| 黄色成人免费观看| 精品成人在线观看| 久久精品视频在线观看| 国产亚洲精品bt天堂精选| 亚洲黄网站在线观看| 欧美国产日韩视频| 亚洲在线免费| 在线观看成人av电影| 日韩网站在线看片你懂的| 国产亚洲一区精品| 午夜在线不卡| 亚洲欧洲精品一区二区三区波多野1战4| 亚洲福利免费| 久久九九国产| 国产在线观看91精品一区| 欧美性猛交xxxx免费看久久久| 99亚洲视频| 久久久91精品| 欧美日产一区二区三区在线观看| 亚洲人成艺术| 最新国产乱人伦偷精品免费网站| 亚洲手机成人高清视频| 精品不卡在线| 亚洲欧洲免费视频| 欧美午夜视频在线观看| 欧美在线二区| 欧美性感一类影片在线播放| 欧美国产精品一区| 亚洲综合视频一区| 国产精品日韩一区二区三区| 亚洲人成毛片在线播放| 国产日韩一区二区三区在线播放| 欧美成va人片在线观看| 欧美精品一区二区精品网| 国产在线精品成人一区二区三区| 欧美亚洲视频一区二区| 亚洲一区二区三区午夜| 欧美午夜精品| 欧美日本亚洲| 久久一区二区视频| 国产日韩精品综合网站| 女人香蕉久久**毛片精品| 国产精品国产三级国产aⅴ浪潮| 免费欧美视频| 裸体一区二区三区| 精品91久久久久| 在线观看视频一区二区欧美日韩| 99国产精品久久久| 亚洲理伦在线| 欧美激情片在线观看| 国产精品一级二级三级| 精品动漫3d一区二区三区免费| 亚洲欧美日韩国产精品| 91久久夜色精品国产九色| 国产精品理论片| 亚洲黄色天堂| 巨胸喷奶水www久久久免费动漫| 国产精品videosex极品| 国产人成一区二区三区影院| 国产视频在线观看一区| 国产欧美日本在线|