在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

輪詢、SSE 和WebSocket哪個更好

jf_78858299 ? 來源:超級架構師 ? 作者:南極真君 ? 2023-02-22 10:39 ? 次閱讀

構建實時Web應用程序有點挑戰,我們需要考慮如何將數據從服務器發送到客戶端。能夠“主動”實現這一功能的技術已經存在了很長時間,并且僅限于兩種通用方法:客戶端請求或服務器請求。

實現這些的幾種方法:

  1. 長/短輪詢(客戶端拉動)
  2. WebSockets(服務器推送)
  3. 服務器發送的事件(服務器推送)
  • 客戶端拉取-客戶端以一定的定期間隔向服務器請求更新
  • 服務器推送-服務器正在主動將更新推送到客戶端(客戶端拉取的反向操作)

圖片

讓我們以一個簡單的用例來比較以上技術,然后選擇合適的技術。

范例:

我們的示例用例非常簡單。我們需要開發一個儀表板Web應用程序,該應用程序可以流轉來自(GitHub / Twitter / .. etc)等網站的活動列表。這個應用程序的目的是從上面列出的各種方法中選擇合適的一種。

1.使用輪詢:

輪詢是一種技術,客戶端通過該技術定期向服務器請求新數據。我們可以通過兩種方式進行輪詢:短輪詢和長輪詢。簡單來說,短輪詢是基于AJAX的計時器,它以固定的延遲進行調用,而長輪詢則基于Comet(即,當服務器事件發生時,服務器將無延遲地將數據發送到客戶端)。兩者都有優點和缺點,并根據用例進行調整。有關深入的詳細信息,請閱讀StackOverflow社區給出的答案。

讓我們看看一個簡單的客戶端長輪詢代碼段的外觀:

/* Client - subscribing to the github events */

subscribe: (callback) => {

const pollUserEvents = () => {

$.ajax({

method: 'GET',

url: 'http://localhost:8080/githubEvents',

success: (data) => {

callback(data) // process the data

},

complete: () => {

pollUserEvents();

},

timeout: 30000

})

}

pollUserEvents()

}

這基本上是一個長輪詢功能,它像往常一樣第一次運行,但是它設置了三十(30)秒的超時,并且在每次對服務器進行Async Ajax調用之后,回調都會再次調用Ajax。

AJAX調用可在HTTP協議上運行,這意味著默認情況下,對同一域的請求應進行多路復用。我們發現這種方法存在一些陷阱。

多路復用(輪詢響應實際上無法同步)

輪詢需要3次往返(TCP SIN,SSL和數據)

超時(如果連接保持空閑時間太長,代理服務器將關閉連接)

您可以在這里閱讀更多關于現實世界的挑戰。

2.使用WebSockets:

WebSocket只是客戶端和服務器之間的持久連接。這是一種通過單個TCP連接提供全雙工通信通道的通信協議。

RFC 6455聲明WebSocket“旨在在HTTP端口80和443上工作,并支持HTTP代理和中介”,從而使其與HTTP協議兼容。為了實現兼容性,WebSocket握手使用HTTP升級標頭將HTTP協議更改為WebSocket協議。HTTP和WebSocket都位于OSI模型的應用程序層,因此依賴于第4層的TCP。

圖片

有一個MDN文檔詳細解釋了WebSocket,我也建議您閱讀它。

讓我們看看一個非常簡單的WebSocket客戶端實現的樣子:

$(function () {

// if user is running mozilla then use it's built-in WebSocket

window.WebSocket = window.WebSocket || window.MozWebSocket;

const connection = new WebSocket('ws://localhost:8080/githubEvents');

connection.onopen = function () {

// connection is opened and ready to use

};

connection.onerror = function (error) {

// an error occurred when sending/receiving data

};

connection.onmessage = function (message) {

// try to decode json (I assume that each message

// from server is json)

try {

const githubEvent = JSON.parse(message.data); // display to the user appropriately

} catch (e) {

console.log('This doesn't look like a valid JSON: '+ message.data);

return;

}

// handle incoming message

};

});

如果服務器支持WebSocket協議,它將同意升級,并將通過響應中的Upgrade標頭傳達此信息。

讓我們看看如何在Node.JS(服務器)中實現:

const express = require('express');

const events = require('./events');

const path = require('path');

const app = express();

const port = process.env.PORT || 5001;

const expressWs = require('express-ws')(app);

app.get('/', function(req, res) {

res.sendFile(path.join(__dirname + '/static/index.html'));

});

app.ws('/', function(ws, req) {

const githubEvent = {}; // sample github Event from Github event API https://api.github.com/events

ws.send('message', githubEvent);

});

app.listen(port, function() {

console.log('Listening on', port);

});

一旦我們從GitHub事件API獲得數據,就可以在建立連接后將其流式傳輸到客戶端。對于我們的場景,這種方法也有一些陷阱。

  • 使用WebSockets,我們需要自己處理許多由HTTP處理的問題。
  • WebSocket是用于傳輸數據的另一種協議,它不會通過HTTP / 2連接自動多路復用。在服務器和客戶端上實現自定義多路復用有點復雜。
  • WebSocket是基于幀的,而不是基于流的。當我們打開網絡標簽。您可以看到WebSocket消息在frame中列出。

圖片

有關WebSocket的詳細信息,請查看這篇很棒的文章,在這里您可以閱讀有關碎片以及如何在后臺進行處理的更多信息。

3.使用SSE:

SSE是一種機制,一旦建立了客戶端-服務器連接,服務器就可以將數據異步推送到客戶端。然后,只要有新的“大塊”數據可用,服務器就可以決定發送數據。可以將其視為單向發布-訂閱模型。

它還提供了一個標準的JavaScript客戶端API,稱為EventSource,已在大多數現代瀏覽器中實現,作為W3C的HTML5標準的一部分。 Polyfills可用于不支持EventSource API的瀏覽器。

圖片

我們可以看到Edge和Opera Mini落后于此實現,對于SSE而言,最重要的案例是針對移動瀏覽器設備,因為這些瀏覽器沒有可行的市場份額。Yaffle是事件源的眾所周知的pollyfill。

由于SSE是基于HTTP的,因此它很自然地與HTTP / 2相適應,并且可以結合使用以實現兩者的最佳選擇:HTTP / 2處理基于多路復用流的有效傳輸層,而SSE為應用程序提供API以實現 推。因此,開箱即用地通過HTTP / 2實現多路復用。連接斷開時會通知客戶端和服務器。通過使用消息維護唯一的ID,服務器可以看到客戶端錯過了n條消息,并在重新連接時發送了未完成消息的積壓。

讓我們看看示例客戶端實現的外觀:

const evtSource = new EventSource('/events');

evtSource.addEventListener('event', function(evt) {

const data = JSON.parse(evt.data);

// Use data here

},false);

此代碼段非常簡單。它連接到我們的源并等待接收消息。現在,示例NodeJS服務器將如下所示。

// events.js

const EventEmitter = require('eventemitter3');

const emitter = new EventEmitter();

function subscribe(req, res) {

res.writeHead(200, {

'Content-Type': 'text/event-stream',

'Cache-Control': 'no-cache',

Connection: 'keep-alive'

});

// Heartbeat

const nln = function() {

res.write('\\n');

};

const hbt = setInterval(nln, 15000);

const onEvent = function(data) {

res.write('retry: 500\\n');

res.write(event: event\\n);

res.write(data: ${JSON.stringify(data)}\\n\\n);

};

emitter.on('event', onEvent);

// Clear heartbeat and listener

req.on('close', function() {

clearInterval(hbt);

emitter.removeListener('event', onEvent);

});

}

function publish(eventData) {

// Emit events here recieved from Github/Twitter APIs

emitter.emit('event', eventData);

}

module.exports = {

subscribe, // Sending event data to the clients

publish // Emiting events from streaming servers

};

// App.js

const express = require('express');

const events = require('./events');

const port = process.env.PORT || 5001;

const app = express();

app.get('/events', cors(), events.subscribe);

app.listen(port, function() {

console.log('Listening on', port);

});

我們從這種方法中獲得的主要好處是:

  • 實施更簡單,數據效率更高
  • 開箱即用地通過HTTP / 2自動多路復用
  • 將客戶端上數據的連接數限制為一個

如何在SSE,WebSocket和Polling中進行選擇?

經過漫長而詳盡的客戶端和服務器實施之后,SSE似乎是我們解決數據交付問題的最終答案。也有一些問題,但是可以解決。

可以利用服務器發送事件的應用程序的一些簡單示例:

  • 實時股價流圖
  • 重要事件的實時新聞報道(發布鏈接,推文和圖片)
  • 由Twitter的流API提供的實時Github / Twitter儀表板墻
  • 監視服務器統計信息(如正常運行時間,運行狀況和正在運行的進程)的監視器。

但是,SSE不僅是其他提供快速更新的方法的可行替代方案。在某些特定情況下,例如在SSE被證明是理想解決方案的情況下,每個人都可以勝過其他人。考慮一個像MMO(大型多人在線)游戲這樣的場景,該場景需要來自連接兩端的大量消息。在這種情況下,WebSockets將壓制SSE。

如果您的用例需要顯示實時的市場新聞,市場數據,聊天應用程序等,例如在我們的案例中,依靠HTTP / 2 + SSE將為您提供有效的雙向通信渠道,同時又能獲得留在其中的好處HTTP世界。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Web
    Web
    +關注

    關注

    2

    文章

    1282

    瀏覽量

    70841
  • 服務器
    +關注

    關注

    13

    文章

    9700

    瀏覽量

    87315
收藏 人收藏

    評論

    相關推薦
    熱點推薦

    Django3如何使用WebSocket實現WebShell

    websocket 服務。 大致看了下覺得這不夠有趣,翻了翻 django 的官方文檔發現 django 原生是不支持 websocket 的,但 django3 之后支持了 asgi 協議可以自己實現
    的頭像 發表于 11-17 09:58 ?4672次閱讀

    一文詳解WebSocket協議

    WebSocket出現之前,一個Web應用(即時聊天、多人協作)的客戶端和服務端之間常見的雙向數據交換方式有短輪詢、長輪詢SSE(Server-Sent Events,服務器發送事
    的頭像 發表于 01-07 11:26 ?8366次閱讀
    一文詳解<b class='flag-5'>WebSocket</b>協議

    protel與protues哪個更好些啊?

    `哪位大神能給個指點,protues與protel在EDA方面哪個更好些?或者在工作崗位上哪個用的多啊?流行趨勢是什么?謝謝了!!!`
    發表于 05-03 12:56

    sse指令集

    sse指令集 SSE(Streaming SIMD Extensions,單指令多數據流擴展)指令集是Intel在Pentium III處理器中率先推出的。其實,早在PIII正式推出之前
    發表于 12-25 10:59 ?1679次閱讀

    什么是SSE/SIMD/Speculative execut

    什么是SSE/SIMD/Speculative execution? SSE(Streaming SIMD Extensions,單一指令多數據流擴展) 英特爾開發的第二代SIMD指令集,有70條指令,
    發表于 02-04 11:14 ?598次閱讀

    什么是Superscalar/SSE/SQRT

    什么是Superscalar/SSE/SQRT   Superscalar: (超標量體系結構)在同一時鐘周期可以執行多條指令流的處理器架構。 SSE: (Streami
    發表于 02-04 11:27 ?701次閱讀

    什么是WebSocket?進行通信解析 WebSocket 報文及實現

    一般情況下全為 0。當客戶端、服務端協商采用 WebSocket 擴展時,這三個標志位可以非0,且值的含義由擴展進行定義。如果出現非零的值,且并沒有采用 WebSocket 擴展,連接出錯。
    的頭像 發表于 05-15 16:59 ?1w次閱讀
    什么是<b class='flag-5'>WebSocket</b>?進行通信解析 <b class='flag-5'>WebSocket</b> 報文及實現

    Python如何爬取實時變化的WebSocket數據

    Python 中的網絡請求庫非常多,Requests 是最常用的請求庫之一,它可以模擬發送網絡請求。但是這些請求都是基于 HTTP 協議的。在面對 WebSocket 的時候 Requests 就發揮不料作用了,必須使用能夠連接 WebSocket 的庫。
    的頭像 發表于 03-11 09:31 ?3772次閱讀
    Python如何爬取實時變化的<b class='flag-5'>WebSocket</b>數據

    WebSocket有什么優點

    WebSocket是一種在單個TCP連接上進行全雙工通信的協議。WebSocket通信協議于2011年被IETF定為標準RFC 6455,并由RFC7936補充規范。WebSocket API也被W3C定為標準。HTML5開始提
    的頭像 發表于 02-15 15:53 ?8513次閱讀
    <b class='flag-5'>WebSocket</b>有什么優點

    WebSocket工作原理及使用方法

    它有很多名字; WebSocketWebSocket協議和WebSocket API。從首選的消息傳遞應用程序到流行的在線多人游戲,WebSocket在當今最常用的Web應用程序中是
    的頭像 發表于 05-05 22:12 ?8195次閱讀
    <b class='flag-5'>WebSocket</b>工作原理及使用方法

    CMOS和CCD哪個視覺效果更好

    電子發燒友網站提供《CMOS和CCD哪個視覺效果更好.zip》資料免費下載
    發表于 01-31 09:27 ?0次下載
    CMOS和CCD<b class='flag-5'>哪個</b>視覺效果<b class='flag-5'>更好</b>

    鴻蒙上WebSocket的使用方法

    WebSocket 是一種網絡通訊協議,很多網絡開發工作者都需要它。本文介紹在 OpenHarmony 上 WebSocket 協議的使用方法。
    的頭像 發表于 03-08 14:17 ?2378次閱讀

    氣動執行器與電動執行器:哪個更好

    氣動執行器與電動執行器:哪個更好
    的頭像 發表于 03-13 16:30 ?7022次閱讀
    氣動執行器與電動執行器:<b class='flag-5'>哪個</b><b class='flag-5'>更好</b>?

    websocket協議的原理

    WebSocket協議是基于TCP的一種新的網絡協議。它實現了瀏覽器與服務器全雙工(full-duplex)通信——允許服務器主動發送信息給客戶端。 WebSocket通信協議于2011年被IETF
    的頭像 發表于 11-09 15:13 ?1600次閱讀
    <b class='flag-5'>websocket</b>協議的原理

    rtthread和freertos哪個更好 選擇哪個

    rtthread和freertos哪個更好 選擇哪個? RT-Thread和FreeRTOS都是流行的開源實時操作系統(RTOS),在選擇哪個更好
    的頭像 發表于 12-08 10:18 ?9814次閱讀
    主站蜘蛛池模板: 岛国毛片一级一级特级毛片 | 二级黄绝大片中国免费视频 | 1024免费永久福利视频 | 人人洗澡人人洗澡人人 | 五月婷婷爱 | 午夜黄 | 57pao成人永久免费视频 | 欧美 ed2k | 成年女人毛片 | 国产综合成色在线视频 | 国产69精品久久久久9牛牛 | 免费播放一区二区三区 | 久久久久久久久久久观看 | 午夜特级毛片 | 天天色操 | 欧美交片 | 日本一区二区三区视频在线观看 | 婷婷 综合网站 | 欧美日韩看片 | 色视频日本 | 欧美拍拍 | 717影院理论午夜伦八戒 | fxxx性xxx性| 成人观看网站a | 交在线观看网站视频 | 午夜一级毛片不卡 | 6月婷婷| 末发育女一区二区三区 | 四虎影视永久在线精品免费播放 | 天天干天天要 | 三级黄色录像 | 你懂的福利网站 | 你懂的福利网站 | 毛片免费高清免费 | 亚洲精品网站日本xxxxxxx | 国产亚洲精品线观看77 | 性生生活三级视频在线观看 | 亚洲人成网站999久久久综合 | 巨骚综合网 | 天天拍夜夜操 | 国产三级在线观看视频 |