自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

五分鐘技術(shù)趣談 | Web端即時(shí)通信方案知多少?

網(wǎng)絡(luò)
隨著互聯(lián)網(wǎng)技術(shù)的發(fā)展,很多Web應(yīng)用開(kāi)始追求用戶(hù)體驗(yàn),無(wú)需刷新就可以讓用戶(hù)可以實(shí)時(shí)感知信息的變化,即時(shí)通信技術(shù)在Web中得到了更廣泛的應(yīng)用。

Part 01

什么是即時(shí)通信? 

即時(shí)通信是一個(gè)實(shí)時(shí)通信系統(tǒng),允許兩人或多人使用網(wǎng)絡(luò)實(shí)時(shí)的傳遞文字消息、文件、語(yǔ)音與視頻交流。即時(shí)通信技術(shù)在Native App中通過(guò)TCP、UDP等協(xié)議可以輕松實(shí)現(xiàn),在Native應(yīng)用較為流行。

受HTTP協(xié)議以及Web客戶(hù)端框架限制,想在Web中實(shí)現(xiàn)真正的即時(shí)通信,可謂是技術(shù)上盡腦汁,極盡所能。從傳統(tǒng)的短輪詢(xún)、長(zhǎng)輪詢(xún)到Comet(長(zhǎng)輪詢(xún)的變體)技術(shù),再到HTML5標(biāo)準(zhǔn)發(fā)布之后的WebSocket、 SSE這類(lèi)技術(shù)的橫空出現(xiàn),使Web端即時(shí)通信的技術(shù)方案越來(lái)越多,實(shí)現(xiàn)也越來(lái)越容易。但是對(duì)于技術(shù)人員面對(duì)不同的場(chǎng)景該如何選擇更實(shí)用的技術(shù)方案呢?

Part 02

Web即時(shí)通信實(shí)現(xiàn)方案有哪些?

2.1 輪詢(xún)的原理與實(shí)現(xiàn)

輪詢(xún)分為短輪詢(xún)與長(zhǎng)輪詢(xún)??

短輪詢(xún):是客戶(hù)端定期向服務(wù)器發(fā)起請(qǐng)求查詢(xún)并獲取數(shù)據(jù),無(wú)論是否有數(shù)據(jù)服務(wù)端都立即響應(yīng)客戶(hù)端的請(qǐng)求,該方案較為簡(jiǎn)單不做過(guò)多介紹。

長(zhǎng)輪詢(xún):是比短輪詢(xún)更有效的一種技術(shù),當(dāng)服務(wù)器收到瀏覽器請(qǐng)求后如果有數(shù)據(jù), 服務(wù)器立刻響應(yīng)請(qǐng)求; 如果沒(méi)有數(shù)據(jù)服務(wù)器就會(huì)hold一段時(shí)間,盡可能長(zhǎng)時(shí)間的保持瀏覽器的連接打開(kāi);這段時(shí)間內(nèi)如果有數(shù)據(jù),服務(wù)器立刻響應(yīng)請(qǐng)求; 如果時(shí)間到了還沒(méi)有數(shù)據(jù), 則響應(yīng)http請(qǐng)求;瀏覽器收到http響應(yīng)后,立即再發(fā)送一個(gè)同樣http請(qǐng)求查詢(xún)是否有數(shù)據(jù);如此重復(fù)下去。下圖是長(zhǎng)輪詢(xún)的交互示意圖:

圖片

長(zhǎng)輪詢(xún)?yōu)g覽器代碼實(shí)現(xiàn)如下:

/* Client - subscribing to the test events */
subscribe: (callback) => {
const pollUserEvents = () => {
$.ajax({
method: 'GET',
url: 'http://localhost:8080/testEvents',
success: (data) => {
callback(data) // process the data
},
complete: () => {
pollUserEvents();
},
timeout: 30000
})
}

2.2 WebSocket的原理與實(shí)現(xiàn)

在2008年中期,開(kāi)發(fā)人員Michael Carter和Lan Hickson敏銳的感受到Comet在實(shí)現(xiàn)復(fù)雜交互時(shí)帶來(lái)的的苦惱和局限,他們制定了一項(xiàng)計(jì)劃并引入現(xiàn)代實(shí)時(shí)雙向通信的新標(biāo)準(zhǔn),創(chuàng)造了WebSocket,并進(jìn)入了W3C HTML草案標(biāo)準(zhǔn),2011年RFC 6455-WebSocket協(xié)議被發(fā)布到了IETF網(wǎng)站。

WebSocket是一個(gè)構(gòu)建在設(shè)備TCP/IP堆棧上的瘦傳輸層,一個(gè)獨(dú)立的基于TCP的協(xié)議,為Web應(yīng)用程序開(kāi)發(fā)人員提供盡可能接近原始的TCP通信層,WebSocket與HTTP唯一的關(guān)系是它的握手是由HTTP服務(wù)器解釋為一個(gè)Upgrade請(qǐng)求。

圖片

WebSocket是一種事件驅(qū)動(dòng)的協(xié)議,這意味著可以將其用于真正的實(shí)時(shí)通信。WebSocket的實(shí)現(xiàn)了一次連接,雙方多次通信的能力。首先由客戶(hù)端發(fā)出WebSocket連接請(qǐng)求,服務(wù)器端進(jìn)行響應(yīng),實(shí)現(xiàn)類(lèi)似TCP握手的動(dòng)作。這個(gè)連接一旦建立起來(lái),在客戶(hù)端和服務(wù)器之間會(huì)一直保持該連接,兩者之間可以直接的進(jìn)行數(shù)據(jù)的互相傳送,并且在連接被關(guān)閉前可以進(jìn)行多次交互。

WebSocket瀏覽器側(cè)代碼實(shí)現(xiàn):

const WebSocket = require('ws');
const ws = new WebSocket('ws://localhost/ws');
ws.on('open', function open() {
    ws.send('something');
});
ws.on('message', function incoming(data) {
    console.log(data);
});

WebSocket服務(wù)端代碼實(shí)現(xiàn):

const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', function connection(ws) {
    ws.on('message', function incoming(message) {
    console.log('received: %s', message);
    });
    ws.send('something');
});

2.3 SSE的原理與實(shí)現(xiàn)

SSE是Server-Sent Events的簡(jiǎn)稱(chēng),是一種可以主動(dòng)從服務(wù)端推送消息給瀏覽器的技術(shù)。SSE也是使用HTTP協(xié)議進(jìn)行交互,嚴(yán)格地說(shuō)HTTP協(xié)議無(wú)法做到服務(wù)器主動(dòng)推送信息給瀏覽器,都是瀏覽器主動(dòng)去請(qǐng)求服務(wù)器端獲取最新的數(shù)據(jù),SSE技術(shù)使服務(wù)器與瀏覽器之間維護(hù)一個(gè)HTTP長(zhǎng)連接,當(dāng)有新數(shù)據(jù)時(shí),服務(wù)端可以通過(guò)這個(gè)長(zhǎng)連接將數(shù)據(jù)發(fā)送給瀏覽器。

圖片

瀏覽器主動(dòng)請(qǐng)求建立一個(gè)格式為text/event-stream的stream流 ,服務(wù)器給瀏覽器發(fā)送的數(shù)據(jù)不是一次性的數(shù)據(jù)包,而是一個(gè)stream流,并且瀏覽器不會(huì)關(guān)閉連接,會(huì)一直等著服務(wù)器發(fā)送新的數(shù)據(jù)流報(bào)文。

客戶(hù)端代碼實(shí)現(xiàn):

var SSENotification = {
  source: null,
  subscribe: function() {
    if ('EventSource' in window) {
      this.source = new EventSource('/sse');
      this.source.addEventListener('message', function(res) {
        const d = res.data;
        window.ChatroomDOM.renderData(JSON.parse(d));
      });
    }
    return this.unsubscribe;
  },
  unsubscribe: function () {
    this.source && this.source.close();
  }
}

服務(wù)器端代碼實(shí)現(xiàn):

router.get('/sse', function(req, res) {
  const connectors = chatRoom.getConnectors();
  const messages = chatRoom.getMessages();
  const response = { code: 200, data: { connectors: connectors, messages: messages } };
  res.writeHead(200, {
    "Content-Type":"text/event-stream",
    "Cache-Control":"no-cache",
    "Connection":"keep-alive",
    "Access-Control-Allow-Origin": '*',
  });
  res.write("retry: 10000\n");
  res.write("data: " + JSON.stringify(response) + "\n\n");
  var unsubscribe = Event.subscribe(function() {
    const connectors = chatRoom.getConnectors();
    const messages = chatRoom.getMessages();
    const response = { code: 200, data: { connectors: connectors, messages: messages } };
    res.write("data: " + JSON.stringify(response) + "\n\n");
  });
  req.connection.addListener("close", function () {
    unsubscribe();
  }, false);
});

Part 03

Web即時(shí)通信方案對(duì)比 

三種即時(shí)通信技術(shù)方案各有優(yōu)缺點(diǎn),三種技術(shù)方案特性對(duì)比如下:

圖片

從對(duì)比可以得出??

長(zhǎng)輪詢(xún):兼容性好,實(shí)現(xiàn)容易;但是由于需要不停向服務(wù)器請(qǐng)求查詢(xún),很多時(shí)候都是無(wú)效報(bào)文,效率低,客戶(hù)端數(shù)量多時(shí)服務(wù)端的壓力較大;適用于掃碼登錄,流程狀態(tài)變化等場(chǎng)景。

WebSocket:支持雙向通信,可以實(shí)現(xiàn)真正的實(shí)時(shí)通信,支持二進(jìn)制數(shù)據(jù)傳輸,基本可以勝任各種即時(shí)通信場(chǎng)景,而且由于WebSocket的首部信息很小,報(bào)文有效載荷高,在海量并發(fā)和客戶(hù)端與服務(wù)器交互負(fù)載流量大的情況下,極大的節(jié)省了網(wǎng)絡(luò)帶寬資源的消耗,有明顯的性能優(yōu)勢(shì);但是WebSocket協(xié)議相對(duì)于HTTP協(xié)議較復(fù)雜,不支持?jǐn)嗑€重連,有一定維護(hù)成本,因此實(shí)際應(yīng)用中需要基于WebSocket開(kāi)源SDK進(jìn)行開(kāi)發(fā);適用于大型聊天App或大型多人在線游戲的場(chǎng)景。

SSE:屬于輕量級(jí)方案,主流瀏覽器都已經(jīng)支持,使用簡(jiǎn)單,默認(rèn)支持?jǐn)嗑€重連,支持自定義事件類(lèi)型;但是SSE長(zhǎng)連接只支持從服務(wù)器向客戶(hù)端發(fā)數(shù)據(jù),并且不支持二進(jìn)制傳輸(需要編碼后傳輸)。適用于服務(wù)器持續(xù)向客戶(hù)端發(fā)送數(shù)據(jù)的場(chǎng)景,如:實(shí)時(shí)股價(jià)流圖、在線音視頻播放、監(jiān)視器客戶(hù)端查看服務(wù)器實(shí)時(shí)信息等。

Part 04

結(jié)束語(yǔ) 

輪詢(xún)、WebSocket、SSE三種技術(shù)方案中該如何選擇?在消息推送時(shí)SSE似乎是我們解決問(wèn)題的最終選擇;但是SSE對(duì)于大型游戲、聊天室時(shí)又有很多力不從心,不如WebSocket全面;而面對(duì)掃碼登錄等簡(jiǎn)單場(chǎng)景時(shí)輪詢(xún)似乎更加簡(jiǎn)單便捷。因此Web端即時(shí)通信方案并不能簡(jiǎn)單的說(shuō)古老的技術(shù)會(huì)被新技術(shù)替代,項(xiàng)目實(shí)施中我們要合理選擇,采用更簡(jiǎn)單、更高效的方案來(lái)完成需求。

責(zé)任編輯:龐桂玉 來(lái)源: 移動(dòng)Labs
相關(guān)推薦

2023-07-02 16:09:57

人工智能人臉識(shí)別

2023-07-23 18:47:59

Docker開(kāi)源

2021-09-18 11:36:38

混沌工程云原生故障

2023-07-16 18:49:42

HTTP網(wǎng)絡(luò)

2023-04-15 20:25:23

微前端

2023-07-23 08:26:39

平安鄉(xiāng)村網(wǎng)絡(luò)

2023-07-02 16:34:06

GPU虛擬化深度學(xué)習(xí)

2023-07-30 10:09:36

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

2023-09-12 07:10:13

Nacos架構(gòu)

2023-07-31 08:55:15

AI技術(shù)網(wǎng)絡(luò)暴力

2023-07-12 15:50:29

機(jī)器學(xué)習(xí)人工智能

2023-08-29 06:50:01

Javamaven

2024-12-18 14:10:33

2023-08-06 07:00:59

Openstack網(wǎng)絡(luò)

2023-08-15 14:46:03

2023-09-17 17:51:43

Android 14

2023-07-12 16:03:37

Android開(kāi)發(fā)架構(gòu)

2023-08-06 06:55:29

數(shù)字可視化物聯(lián)網(wǎng)

2023-09-02 20:22:42

自動(dòng)化測(cè)試軟件開(kāi)發(fā)

2023-08-07 06:35:07

系統(tǒng)限流
點(diǎn)贊
收藏

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