Web應用從伺服器主動推送資料到客戶端的方式

2022-09-09 05:03:13 字數 4550 閱讀 7301

comet實現框架

伺服器和內部構件

4. ==websocket==

總結

1.應用伺服器如何確定每乙個應用所在的裝置

2.服務端把訊息推到哪,客戶端又不像伺服器有乙個固定的位址

服務端主動推送到客戶端是怎麼乙個過程?

結合乙個實際問題分析下:

我們先做做技術調研,這種瀏覽器與伺服器實時通訊的方式有哪些方式。

這是我們最自然想到的。 採用常規ajax輪詢的方式,每10s或者30s輪詢一次,既可以判斷出有有多少個新訂單進入,且這種時間間隔對於訊息提醒也是可以接受的。這種技術方式實現起來非常簡單,目前的機器都是可以機器的,前端瀏覽器也都支援。

但是這種方式會有非常嚴重的問題,就是需要不斷的向伺服器傳送訊息詢問,如果有1w個商家開啟了瀏覽器,採用10s輪詢的方式,則伺服器則會承擔1000 的qps,這1w個商家可能只有10個有訂單通知;這種方式會對伺服器造成極大的效能浪費。

還有乙個類似的輪詢是使用jsonp跨域請求的方式輪詢,在實現起來有差別,但基本原理都是相同的,都是客戶端不斷的向伺服器發起請求。

優點

實現簡單。

缺點

這是通過模擬伺服器發起的通訊,不是實時通訊,不顧及應用的狀態改變而盲目檢查更新,導致伺服器資源的浪費,且會加重網路負載,拖累伺服器。

iframe 是很早就存在的一種 html 標記, 通過在 html 頁面裡嵌入乙個隱蔵幀,然後將這個隱蔵幀的 src 屬性設為對乙個長連線的請求,伺服器端就能源源不斷地往客戶端輸入資料。

優點

這種方式每次資料傳送不會關閉連線,連線只會在通訊出現錯誤時,或是連線重建時關閉(一些防火牆常被設定為丟棄過長的連線, 伺服器端可以設定乙個超時時間, 超時後通知客戶端重新建立連線,並關閉原來的連線)。

缺點

ie、morzilla firefox 下端的進度欄都會顯示載入沒有完成,而且 ie 上方的圖示會不停的轉動,表示載入正在進行。

google 的天才們使用乙個稱為「htmlfile」的 activex 解決了在 ie 中的載入顯示問題,並將這種方法用到了 gmail+gtalk 產品中。alex russell 在 「what else is burried down in the depth』s of google』s amazing j**ascript?」文章中介紹了這種方法。zeitoun **提供的 comet-iframe.tar.gz,封裝了乙個基於 iframe 和 htmlfile 的 j**ascript comet 物件,支援 ie、mozilla firefox 瀏覽器,可以作為參考。

我們常用的網頁版的gtalk就是這種實現方式,google的開發人員使使用乙個稱為「htmlfile」的 activex 解決了在 ie 中的載入顯示問題。

comet是一種用於web的推送技術,能使伺服器實時地將更新的資訊傳送到客戶端,而無須客戶端發出請求,目前有兩種實現方式:

長輪詢 (long polling) 是在開啟一條連線以後保持,等待伺服器推送來資料再關閉,可以採用http長輪詢xhr長輪詢兩種方式。

http 和jsonp方式的長輪詢

把 script 標籤附加到頁面上以讓指令碼執行。伺服器會掛起連線直到有事件發生,接著把指令碼內容傳送回瀏覽器,然後重新開啟另乙個 script 標籤來獲取下乙個事件,從而實現長輪詢的模型。

xhr長輪詢

這種方式是使用比較多的長輪詢模式。

客戶端開啟乙個到伺服器端的 ajax 請求然後等待響應;伺服器端需要一些特定的功能來允許請求被掛起,只要一有事件發生,伺服器端就會在掛起的請求中送回響應並關閉該請求。客戶端 j**ascript 響應處理函式會在處理完伺服器返回的資訊後,再次發出請求,重新建立連線;如此迴圈。

現在瀏覽器已經支援cros的跨域方式請求,因此http和jsonp的長輪詢方式是慢慢被淘汰的一種技術,建議採用xhr長輪詢。

長輪詢優缺點:

優點

客戶端很容易實現良好的錯誤處理系統和超時管理,實現成本與ajax輪詢的方式類似。

缺點

需要伺服器端有特殊的功能來臨時掛起連線。當客戶端發起的連線較多時,伺服器端會長期保持多個連線,具有一定的風險。

cometd

cometd 框架是基於 http 的事件驅動通訊解決方案,使用了bayeux通訊協議,提供了乙個 j**a 伺服器部件和乙個 j**a 客戶端部件,還有乙個基於 jquery 和 dojo 的 j**ascript 客戶端庫。

bayeux 通訊協議主要是基於 http,提供了客戶端與伺服器之間的響應性雙向非同步通訊。bayeux 協議基於通道進行通訊,通過該通道從客戶端到伺服器、從伺服器到客戶端或從客戶端到客戶端(但是是通過伺服器)路由和傳送訊息。bayeux 是一種 「發布- 訂閱」 協議。

cometd 與三個傳輸協議繫結在一起:json、jsonp 和 websocket。他們都依賴於 jetty continuations 和 jetty websocket api。在預設情況下,可以在 jetty 6、jetty 7、和 jetty 8 中以及其他所有支援 servlet 3.0 specification 的服務中使用 cometd。

atmosphere框架

atmosphere提供了乙個通用 api,以便使用許多 web 伺服器(包括 tomcat、jetty、glassfish、weblogic、grizzly、jbossweb、jboss 和 resin)的 comet 和 websocket 特性。它支援任何支援 servlet 3.0 specification 的 web 伺服器。

atmosphere 提供了乙個 jquery 客戶端庫,該庫可以使連線設定變得更容易,它能夠自動檢測可以使用的最佳傳輸協議(websockets 或 cometd)。atmosphere 的 jquery 外掛程式的用法與 html5 websockets api 相似。

pushlet

pushlet 使用了觀察者模型:客戶端傳送請求,訂閱感興趣的事件;伺服器端為每個客戶端分配乙個會話 id 作為標記,事件源會把新產生的事件以多播的方式傳送到訂閱者的事件佇列裡。

pushlet 最後更新於2023年2月5號,之後至今沒有再更新。

cometd 和atmosphere框架參見示例** (

comet實現要點
不要在同一客戶端同時使用超過兩個的 http 長連線

http 1.1 規範中規定,客戶端不應該與伺服器端建立超過兩個的 http 連線, 新的連線會被阻塞,在ie瀏覽器中嚴格遵守了這種規定。

伺服器端的效能和可擴充套件性

一般 web 伺服器會為每個連線建立乙個執行緒,如果在大型的商業應用中使用 comet,伺服器端需要維護大量併發的長連線。在這種應用背景下,伺服器端需要考慮負載均衡和集群技術;或是在伺服器端為長連線作一些改進。

在客戶和伺服器之間保持「心跳」資訊

在瀏覽器與伺服器之間維持乙個長連線會為通訊帶來一些不確定性:因為資料傳輸是隨機的,客戶端不知道何時伺服器才有資料傳送。伺服器端需要確保當客戶端不再工作時,釋放為這個客戶端分配的資源,防止記憶體洩漏。因此需要一種機制使雙方知道雙方都在正常執行。

伺服器端在阻塞讀時會設定乙個時限,超時後阻塞讀呼叫會返回,同時發給客戶端沒有新資料到達的心跳資訊。此時如果客戶端已經關閉,伺服器往通道寫資料會出現異常,伺服器端就會及時釋放為這個客戶端分配的資源。

如果客戶端使用的是基於 ajax 的長輪詢方式;伺服器端返回資料、關閉連線後,經過某個時限沒有收到客戶端的再次請求,會認為客戶端不能正常工作,會釋放為這個客戶端分配、維護的資源。

當伺服器處理資訊出現異常情況,需要傳送錯誤資訊通知客戶端,同時釋放資源、關閉連線。

websocket是html5開始提供的一種在單個 tcp 連線上進行全雙工通訊的協議。websocket通訊協議於2023年被ietf定為標準rfc 6455,websocketapi被w3c定為標準。在websocket api中,瀏覽器和伺服器只需要做乙個握手的動作,然後,瀏覽器和伺服器之間就形成了一條快速通道。兩者之間就直接可以資料互相傳送。

瀏覽器支援

瀏覽器版本支援

chrome

4+firefox

4+ie

10+opera

10+safari

5+詳情檢視 browser compatibility

實現

websocket的實現已經有很多種版本,詳細可以檢視demo。

總結下來長輪詢不是乙個很好的方案,而且對於伺服器而言是有風險的;另外支援websocket協議的瀏覽器都比較新,特比是ie需要10以上的版本;而我們的業務是面向於商家端,商家的瀏覽器版本相對較低,很多對websocket都不支援;相對而言comet的方式比較適合,也有相應的實現框架,實現成本最低;因此最後我們還是決定使用comet的方式來實現,後面上線執行一段時間之後再來給大家介紹。

伺服器主動推送

1.客戶端輪詢 ajax定時拉取 2.服務端主動推送 websocket 全雙工的,本質是乙個額外的tcp連線,建立和關閉時握手使用的http協議,其他資料傳輸不使用 http協議更加複雜一些,適用於需要進行複雜雙向資料通訊的場景 3.服務端主動推送 sse server send event ht...

linux UDP伺服器主動傳送資料

tcp udp的連線 客戶端自己的埠號和ip位址與伺服器是不一樣的 比如使用udp 埠號是一樣的,客戶端以伺服器為準 客戶端是192.168.1.22,電腦虛擬機器是192.168.1.29 客戶端 powerpc 設定為1.29 埠號 埠號可以寫成不一樣 mac位址可以亂寫,但不能不寫 unsig...

Web 伺服器與 應用程式伺服器

一 web伺服器 1 常用的web伺服器又apache iis等 2 web伺服器的特點 web伺服器可以解析 handles http協議。當web伺服器接收到乙個http請求 request 會返回乙個http響應 response 例如送回乙個html頁面。web伺服器的 模型 delegat...