成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

數(shù)據(jù)不夠?qū)崟r(shí):試試長(zhǎng)連接?

網(wǎng)絡(luò) 網(wǎng)絡(luò)管理
長(zhǎng)輪詢很完美地解決了短輪詢的問(wèn)題,首先服務(wù)端在沒(méi)有數(shù)據(jù)更新的情況下沒(méi)有給客戶端返回?cái)?shù)據(jù),所以避免了客戶端大量的重復(fù)請(qǐng)求。

背景

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

輪詢

輪詢就是采用循環(huán)http請(qǐng)求的方式,通過(guò)重復(fù)的接口請(qǐng)求去獲取最新的數(shù)據(jù)。

短輪詢 (polling)

短輪詢可能是我們用的最多的一種實(shí)時(shí)刷新數(shù)據(jù)的方式了,我們?cè)谥v輪詢方案時(shí),大部分指的就是短輪詢,其實(shí)現(xiàn)方式和普通的接口無(wú)異,改造也只要前端增加定時(shí)器或useRequest配置輪詢參數(shù)即可,其原理也非常簡(jiǎn)單,如下圖,如果是http1.1及以上,TCP連接可以復(fù)用,當(dāng)然http1.0及以下也是可以使用,但消耗會(huì)更多。短輪詢的特點(diǎn)就是接口請(qǐng)求立即會(huì)返回,每次請(qǐng)求都可以理解為是一次新的請(qǐng)求。

圖片

短輪詢的優(yōu)缺點(diǎn)

短輪詢最大的優(yōu)點(diǎn)就是簡(jiǎn)單,前端設(shè)置時(shí)間間隔,定時(shí)去請(qǐng)求數(shù)據(jù),而服務(wù)端只需同步的查詢數(shù)據(jù)返回即可,但缺點(diǎn)也顯而易見(jiàn):

  1. 無(wú)用請(qǐng)求過(guò)多:從下圖可以看出,每隔固定時(shí)間,一定有請(qǐng)求發(fā)出,且每次接口可能返回一樣的數(shù)據(jù)或返回空結(jié)果,服務(wù)端會(huì)重復(fù)查詢數(shù)據(jù)庫(kù)、前端會(huì)重復(fù)重渲染
  2. 實(shí)時(shí)性不可控,如數(shù)據(jù)更新了,但輪詢請(qǐng)求剛結(jié)束一輪,會(huì)造成輪詢間隔內(nèi)數(shù)據(jù)都得不到更新

圖片

長(zhǎng)輪詢 (long polling)

看完了上面關(guān)于短輪詢的介紹,我們知道了輪詢有兩個(gè)主要的缺陷:一個(gè)是無(wú)用請(qǐng)求過(guò)多,另外一個(gè)是數(shù)據(jù)實(shí)時(shí)性不可控。為了解決這兩個(gè)問(wèn)題,于是有了更進(jìn)一步的長(zhǎng)輪詢方案。

圖片

在上圖中,客戶端發(fā)起請(qǐng)求后,服務(wù)端發(fā)現(xiàn)當(dāng)前沒(méi)有新的數(shù)據(jù),這個(gè)時(shí)候服務(wù)端沒(méi)有立即返回請(qǐng)求,而是將請(qǐng)求掛起,在等待一段時(shí)間后(一般為30s或者是60s,設(shè)置一個(gè)超時(shí)返回主要是為了考慮過(guò)長(zhǎng)的無(wú)數(shù)據(jù)連接占用會(huì)被網(wǎng)關(guān)或者某層中間件斷開(kāi)甚至是被運(yùn)營(yíng)商斷開(kāi)),如發(fā)現(xiàn)還是沒(méi)有數(shù)據(jù)更新的話,就返回一個(gè)空結(jié)果給客戶端。客戶端在收到服務(wù)端的回復(fù)后,立即再次向服務(wù)端發(fā)送新的請(qǐng)求。這次服務(wù)端在接收到客戶端的請(qǐng)求后,同樣等待了一段時(shí)間,這次好運(yùn)的是服務(wù)端的數(shù)據(jù)發(fā)生了更新,服務(wù)端給客戶端返回了最新的數(shù)據(jù)。客戶端在拿到結(jié)果后再次發(fā)送下一個(gè)請(qǐng)求,如此反復(fù)。

長(zhǎng)輪詢的優(yōu)缺點(diǎn)

長(zhǎng)輪詢很完美地解決了短輪詢的問(wèn)題,首先服務(wù)端在沒(méi)有數(shù)據(jù)更新的情況下沒(méi)有給客戶端返回?cái)?shù)據(jù),所以避免了客戶端大量的重復(fù)請(qǐng)求。再者客戶端在收到服務(wù)端的返回后,馬上發(fā)送下一個(gè)請(qǐng)求,這就保證了更好的數(shù)據(jù)實(shí)時(shí)性。不過(guò)長(zhǎng)輪詢也有缺點(diǎn):

  • 服務(wù)端資源大量消耗: 服務(wù)端會(huì)一直hold住客戶端的請(qǐng)求,這部分請(qǐng)求會(huì)占用服務(wù)器的資源。對(duì)于某些語(yǔ)言來(lái)說(shuō),每一個(gè)HTTP連接都是一個(gè)獨(dú)立的線程,過(guò)多的HTTP連接會(huì)消耗掉服務(wù)端的內(nèi)存資源。
  • 難以處理數(shù)據(jù)更新頻繁的情況: 如果數(shù)據(jù)更新頻繁,會(huì)有大量的連接創(chuàng)建和重建過(guò)程,這部分消耗是很大的。雖然HTTP有TCP連接復(fù)用,但每次拿到數(shù)據(jù)后客戶端都需要重新請(qǐng)求,因此相對(duì)于WebSocket和SSE它多了一個(gè)發(fā)送新請(qǐng)求的階段,對(duì)實(shí)時(shí)性和性能還是有影響的。

從上面的描述來(lái)看,長(zhǎng)輪詢的次數(shù)和時(shí)延似乎可以更少,那是不是長(zhǎng)輪詢更好呢?其實(shí)不是的,這個(gè)兩種輪詢方式都有優(yōu)劣勢(shì)和適合的場(chǎng)景。

短輪詢 ,長(zhǎng)輪詢?cè)趺催x?

長(zhǎng) 輪詢多用于操作頻繁,點(diǎn)對(duì)點(diǎn)的通訊,而且連接數(shù)不能太多情況,每個(gè)TCP連接都需要三步握手,這需要時(shí)間,如果每個(gè)操作都是先連接,再操作的話那么處理速度會(huì)降低很多,所以每個(gè)操作完后都不斷開(kāi),次處理時(shí)直接發(fā)送數(shù)據(jù)包就OK了,不用建立TCP連接。例如:數(shù)據(jù)庫(kù)的連接用長(zhǎng)連接, 如果用短連接頻繁的通信會(huì)造成socket錯(cuò)誤,而且頻繁的socket 創(chuàng)建也是對(duì)資源的浪費(fèi)。

而像WEB網(wǎng)站的http服務(wù)一般都用短 輪詢,因?yàn)殚L(zhǎng)連接對(duì)于服務(wù)端來(lái)說(shuō)會(huì)耗費(fèi)一定的資源,而像WEB網(wǎng)站這么頻繁的成千上萬(wàn)甚至上億客戶端的連接用短連接會(huì)更省一些資源,如果用長(zhǎng)連接,而且同時(shí)有成千上萬(wàn)的用戶,如果每個(gè)用戶都占用一個(gè)連接的話,那可想而知吧。所以并發(fā)量大,但每個(gè)用戶無(wú)需頻繁操作情況下需用短連好。

長(zhǎng)連接

?WebSocket?

上面說(shuō)到長(zhǎng)輪詢不適用于服務(wù)端資源頻繁更新的場(chǎng)景,而解決這類問(wèn)題的一個(gè)方案就是WebSocket。用最簡(jiǎn)單的話來(lái)介紹WebSocket就是:客戶端和服務(wù)器之間建立一個(gè)持久的長(zhǎng)連接,這個(gè)連接是雙工的,客戶端和服務(wù)端都可以實(shí)時(shí)地給對(duì)方發(fā)送消息。下面是WebSocket的圖示:

圖片

WebSocket對(duì)于前端的同學(xué)來(lái)說(shuō)是非常常見(jiàn)了,因?yàn)闊o(wú)論是webpack還是vite,用來(lái)HMR的reload就是通過(guò)WebSocket來(lái)進(jìn)行的,有代碼改動(dòng),工程重新編譯,新變更的模塊通知到瀏覽器加載新的模塊,這里的通知瀏覽器加載新模塊就是通過(guò)WebSocket的進(jìn)行的。如上圖,通過(guò)握手(協(xié)議轉(zhuǎn)換)建立連接后,雙方就保持持久連接,由于歷史的關(guān)系,WebSocket建立連接是依賴HTTP的,但是其建連請(qǐng)求有明顯的特征,目的是客戶端和服務(wù)端都能識(shí)別并保持連接。

請(qǐng)求特征

請(qǐng)求頭特征

  • HTTP 必須是 1.1 GET 請(qǐng)求
  • HTTP Header 中 Connection 字段的值必須為 Upgrade
  • HTTP Header 中 Upgrade 字段必須為 websocket
  • Sec-WebSocket-Key 字段的值是采用 base64 編碼的隨機(jī) 16 字節(jié)字符串
  • Sec-WebSocket-Protocol 字段的值記錄使用的子協(xié)議,比如 binary base64
  • Origin 表示請(qǐng)求來(lái)源

響應(yīng)頭特征

  • 狀態(tài)碼是 101 表示 Switching Protocols
  • Upgrade / Connection / Sec-WebSocket-Protocol 和請(qǐng)求頭一致
  • Sec-WebSocket-Accept 是通過(guò)請(qǐng)求頭的 Sec-WebSocket-Key 生成

圖片

兼容性

WebSocket 協(xié)議在2008年誕生,2011年成為國(guó)際標(biāo)準(zhǔn)。現(xiàn)在所有瀏覽器都已經(jīng)支持了。

圖片

實(shí)現(xiàn)一個(gè)簡(jiǎn)單的 WebSocket

基于原生WebSocket我們實(shí)現(xiàn)一個(gè)簡(jiǎn)單的長(zhǎng)連。

連接

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

圖片

發(fā)送消息

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

圖片

監(jiān)聽(tīng)消息

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

圖片

關(guān)閉連接

ws.close();

圖片

?在工程上使用WebSocket?

在工程上,很少直接基于原生WebSocket實(shí)現(xiàn)業(yè)務(wù)需求,使用WebSocket需要完成下面幾個(gè)問(wèn)題:

  • 鑒權(quán):防止惡意連接連接進(jìn)來(lái)接收消息
  • 心跳:客戶端意外斷開(kāi),導(dǎo)致死鏈占用服務(wù)端資源,長(zhǎng)時(shí)間無(wú)消息的連接可能會(huì)被中間網(wǎng)關(guān)或運(yùn)營(yíng)商斷開(kāi)
  • 登錄:通過(guò)建連需要識(shí)別出該連接是哪個(gè)用戶,有無(wú)權(quán)限,需要推送哪些消息
  • 日志:監(jiān)控連接,錯(cuò)誤上報(bào)
  • 后臺(tái):能方便的查看在線連接的客戶端數(shù)量,消息傳輸量

服務(wù)端推送(SSE)

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

圖片

?和 Websocket對(duì)比?

SSE

WebSocket

單向:僅服務(wù)端能發(fā)送消息

雙向:客戶端、服務(wù)端雙向發(fā)送

僅文本數(shù)據(jù)

二進(jìn)制、文本都可

常規(guī)HTTP協(xié)議

WebSocket協(xié)議

?兼容性?

圖片

?數(shù)據(jù)格式?

服務(wù)器向?yàn)g覽器發(fā)送的 SSE 數(shù)據(jù),必須是 UTF-8 編碼的文本,

響應(yīng)頭

Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive

數(shù)據(jù)傳輸

服務(wù)端每次發(fā)送消息,由若干message?組成,使用\n\n?分隔,如果單個(gè)messag?過(guò)長(zhǎng),可以用\n分隔。

field取值

data
event
id
retry

例子

// 注釋,用于心跳包
: this is a test stream\n\n
// 設(shè)置斷鏈1000ms重試一次
retry:1000 \n\n
event: 自定義消息\n\n

data: some text\n\n

data: another message\n
data: with two lines \n\n

?實(shí)現(xiàn)一個(gè)簡(jiǎn)單的SSE?

web端

實(shí)例化EventSource?,監(jiān)聽(tīng)open、message、error

const source = new EventSource(url, { withCredentials: true });
// 監(jiān)聽(tīng)消息
source.onmessage = function (event) {
// handle message
};
source.addEventListener('message', function (event) {
// handle message
}, false);

// 監(jiān)聽(tīng)錯(cuò)誤
source.onerror = function (event) {
// handle error
};
source.addEventListener('error', function (event) {
// handle error
}, false);

// 關(guān)閉連接
source.close()

服務(wù)端

以nodejs為例,服務(wù)端代碼和普通請(qǐng)求無(wú)異,并沒(méi)有新的處理類庫(kù)。

    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并不是新的通信協(xié)議,其本質(zhì)是在普通HTTP請(qǐng)求的基礎(chǔ)上定義一個(gè)Content-Type?,保持上連接,通過(guò)普通的接口也能模擬出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) => {
// 每次服務(wù)端寫(xiě)入response的數(shù)據(jù),都會(huì)傳輸過(guò)來(lái),并產(chǎn)生一次onprogress事件
console.log("onprogress", xhr.responseText);
};
xhr.send();

參考文獻(xiàn)

rfc6455.pdf[1]

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

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

HTTP長(zhǎng)連接實(shí)現(xiàn)原理 - 掘金[4]

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

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

責(zé)任編輯:武曉燕 來(lái)源: ELab團(tuán)隊(duì)
相關(guān)推薦

2017-02-08 17:29:17

遷移大數(shù)據(jù)深度學(xué)習(xí)

2018-06-06 11:01:25

HTTP長(zhǎng)連接短連接

2022-10-24 08:14:35

長(zhǎng)連接負(fù)載均衡Conusmer

2022-12-02 13:49:41

2021-02-26 12:37:39

WebSocketOkHttp連接

2021-03-24 09:06:01

MySQL長(zhǎng)連接短連接

2024-06-06 09:12:40

數(shù)據(jù)庫(kù)SQLServer

2015-06-11 10:57:10

2020-09-05 17:00:20

HTTP長(zhǎng)連接短連接

2019-01-07 12:02:02

TCP長(zhǎng)連接Java

2023-08-09 09:33:01

ChatGPT流式網(wǎng)絡(luò)

2013-12-12 10:00:03

大數(shù)據(jù)

2023-12-28 10:58:45

2019-04-15 14:37:23

HTTPTCP長(zhǎng)連接

2024-06-03 08:26:35

2021-09-13 10:03:54

藍(lán)牙連接藍(lán)牙藍(lán)牙設(shè)備

2011-07-25 16:47:01

HTTP Server PUSH

2024-07-16 10:25:27

2021-07-05 10:13:29

人工智能AI數(shù)據(jù)

2015-10-09 16:14:37

數(shù)據(jù)開(kāi)放
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 91精品国产高清一区二区三区 | 久在线视频 | 国产日韩欧美在线 | 亚洲欧美一区二区三区1000 | 黄网站免费在线看 | 99久久精品国产毛片 | 午夜精品一区二区三区在线观看 | 男人的天堂在线视频 | 国内精品久久久久久久 | 精品久久久久久亚洲国产800 | 国产 欧美 日韩 一区 | 亚洲精品国产综合区久久久久久久 | 天天爱av | 日韩一级免费大片 | 国产精品久久久久国产a级 欧美日本韩国一区二区 | 午夜网 | 91偷拍精品一区二区三区 | 久久久999免费视频 999久久久久久久久6666 | 久久成人免费 | 亚洲视频在线看 | 日韩在线观看一区 | 亚洲欧美日韩电影 | 欧美黄色片| 国产黄色小视频在线观看 | 久久国产精品偷 | 亚洲激情一区二区三区 | 国产欧美在线一区 | 中文字幕亚洲视频 | 激情六月丁香 | 久久久人成影片免费观看 | 国外成人在线视频网站 | 久久午夜国产精品www忘忧草 | 成人在线观看免费爱爱 | 黄在线 | 91久久国产综合久久91精品网站 | 亚洲欧美激情精品一区二区 | 欧洲精品久久久久毛片完整版 | 99精品久久| av日韩在线播放 | 91在线免费观看网站 | 美女视频黄色的 |