當前位置:
首頁 > 最新 > 詳解如何實現在線聊天系統中的實時消息獲取

詳解如何實現在線聊天系統中的實時消息獲取

全文共3682 字,預計閱讀時間: 10 分鐘

序言

傳統web瀏覽器應用採用客戶端主動請求方式,只有在收到瀏覽器請求時服務端才返回消息,這種模式已經不能滿足日益多樣化的web應用需求,例如:

在線聊天系統:需要實時獲取聊天消息。

實時監控系統:需要實時獲取監控對象狀態。如儀錶讀數、告警信息等。

隨著html技術演進,發展出了多種伺服器推送技術,用於伺服器向瀏覽器客戶端推送消息。

Ajax輪詢

採用Ajax定時向服務端發送請求檢查有無消息更新。網頁定時向伺服器發送請求,若伺服器有消息推送,則返回消息,否則返回空消息,如下圖所示:

這種輪詢方式需要發送大量無效請求,大大消耗了伺服器資源,且推送消息的實時性較低。

Ajax長輪詢

Ajax長輪詢對前面的Ajax輪詢方式做了改進,服務端收到請求後,不再立即返回,而是等待有消息推送時返回。網頁收到服務端返回的消息後,立即發起一個新的請求,等待下一個推送消息。

採用這種方式的服務端實現比前者複雜,需要維護一個客戶端建立的連接列表,當產生對某個客戶端的推送消息後找到對應的連接並發送。優勢是減少了輪詢消耗,發送事件的實時性得到增強。

Server-Send Event

Server-Send Event是html5標準新增的技術,它延用了Ajax長輪詢的思路,並對其進行了一些規範。Server-Send Event讓服務端可以向客戶端流式發送文本消息,並在發送完一個消息後保持請求不結束,連接始終保持。如下圖所示:

網頁調用EventSource介面向伺服器發送請求:

Javascript 代碼

1 var source = new EventSource("http://localhost:8080");

2source.addEventListener("message", function(e) { console.log(e.data); }, false);

伺服器返回的Content-Type頭必須為text/event-stream,且返回完一個消息後不關閉請求,後續消息仍然使用同一個請求返回。瀏覽器會自動以換行符識別每個消息。

響應頭-Java 代碼

1 Content-Type: text/event-stream

2 X-Accel-Buffering: no

響應體-Java 代碼

1 event: userlogin

2 data: {"username": "John123"}

3

4 event: message

5 data: 123

如果服務端返回的消息通過nginx等代理伺服器返回給客戶端時,可能受到nginx緩存機制的影響。某些情況下,nginx會將服務端返回體緩存起來,等待所有返回接受完畢後再統一返回給客戶端,在server-send event情況下將導致客戶端無法及時接收到消息。需要在返回頭中添加X-Accel-Buffering: no,以防止nginx做緩存。

使用華為API gateway提供

Server-Send Event類型的

API服務建立後端服務

登錄華為雲https://console.huaweicloud.com/,創建彈性雲伺服器

輸入apt install nodejs安裝nodejs,使用nodejs創建伺服器,並輸入下列示例代碼。

Javascript 代碼

01 var http = require("http");

02

03 http.createServer(function (req, res) {

04 if (req.url === "/stream") {

05 res.writeHead(200, {

06 "Content-Type":"text/event-stream",

07 "X-Accel-Buffering":"no",

08 });

09 res.write("data: " + (new Date()) + "

");

10 interval = setInterval(function () {

11 res.write("data: " + (new Date()) + "

");12 }, 1000);

13

14 req.connection.addListener("close", function () {

15 clearInterval(interval);

16 }, false);

17 }

18 }).listen(8080);

上面代碼是伺服器每秒向客戶端發送時間的示例。將上面的代碼保存為server.js,然後執行nodejs server.js &

就啟動了監聽在8080埠的伺服器。

添加安全組

將8080埠添加到安全組規則,使得外部可以訪問雲伺服器的8080埠。

創建API

API網關提供從內網訪問雲伺服器的能力,不需要申請公網彈性IP,就可以通過VPC通道開放API。

登錄華為雲https://console.huaweicloud.com/apig/ ,首先創建VPC通道,埠為8080

將彈性雲伺服器添加到VPC通道:

創建API,認證類型選擇APP

「請求Path」填「/stream」,「開啟跨域」選項選擇開啟

創建API完成後,發布API到RELEASE環境。

創建APP並綁定API

在應用管理界面創建一個APP,並綁定剛剛創建的API。

創建OPTIONS方法的API

OPTIONS方法的API是提供給瀏覽器發送跨域請求的預請求使用,同樣選擇開啟跨域(CORS),並將後端配置為Mock。

點完成創建API後,發布API到RELEASE環境。

創建網頁,訪問API

1.要訪問APP認證方式的API,需要通過APP的key和secret生成簽名,才能校驗通過。生成簽名使用下面鏈接下載的javascript SDK

https://console.huaweicloud.com/apig/?agencyId=c65a0db86e514fe298cdc57c6273411a?ion=cn-south-1&locale=zh-cn#/apig/manager/useapi/sdk

2.由於IE瀏覽器不支持Server Sent Event,需要從https://github.com/Yaffle/EventSource/下載瀏覽器兼容的Server Sent Event實現。

搜索並刪除下面四行代碼:

Javascript 代碼

1 if (url.slice(0, 5) !== "data:" &&

2 url.slice(0, 5) !== "blob:") {

3 requestURL = url + (url.indexOf("?", 0) === -1 ? "?" : "&") + "lastEventId="+ encodeURIComponent(lastEventId);

4 }

3.創建index.html,內容如下:

Html 代碼

01

02

03 SSE APP test

04

05

06 SSE APP test

07

08 09

10

11

12

13

29

30

將剛剛創建的APP的AppKey和AppSecret填入上面指定位置。在本地用瀏覽器打開此頁面,可以看到頁面上顯示的時間每秒刷新一次。

以上就是對如何實現在線聊天系統中的實時消息獲取的詳解,想要了解更多,點擊「閱讀原文」立即體驗一番吧~

點我立即體驗


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 中間件小哥 的精彩文章:

淺談API網關如何承載API經濟生態鏈

TAG:中間件小哥 |