為什麼我們需要HTML5 WebSocket
HTML5 WebSocket簡介
HTML5作為下一代的 Web 標準,它擁有許多引人注目的新特性,如 Canvas、本地儲存、多媒體程式設計介面、WebSocket等等。這其中有“Web 的 TCP ”之稱的WebSocket格外吸引開發人員的注意。WebSocket的出現使得瀏覽器提供對Socket的支援成為可能,從而在瀏覽器和伺服器之間提供了一個基於TCP連線的雙向通道。Web開發人員可以非常方便地使用WebSocket構建實時web應用,開發人員的手中從此又多了一柄神兵利器。
實時Web應用的窘境
Web應用的資訊互動過程通常是客戶端通過瀏覽器發出一個請求,伺服器端接收和稽核完請求後進行處理並返回結果給客戶端,然後客戶端瀏覽器將資訊呈現出來,這種機制對於資訊變化不是特別頻繁的應用尚能相安無事,但是對於那些實時要求比較高的應用來說,比如說線上遊戲、股票查詢,線上證券、裝置監控、新聞線上播報、RSS訂閱推送等等,當客戶端瀏覽器準備呈現這些資訊的時候,這些資訊在伺服器端可能已經過時了。所以保持客戶端和伺服器端的資訊同步是實時 Web 應用的關鍵要素,對 Web 開發人員來說也是一個難題。在WebSocket規範出來之前,開發人員想實現這些實時的Web應用,不得不採用一些折衷的方案,其中最常用的就是輪詢(Polling)和Comet技術。而Comet 技術實際上是輪詢技術的改進,又可細分為兩種實現方式,一種是長輪詢機制,一種稱為流技術。下面我們簡單介紹一下這幾種技術:輪詢:
這是最早的一種實現實時Web應用的方案。客戶端以一定的時間間隔向服務端發出請求,以頻繁請求的方式來保持客戶端和伺服器端的同步。這種同步方案的最大問題是,當客戶端以固定頻率向伺服器發起請求的時候,伺服器端的資料可能並沒有更新,這樣會帶來很多無謂的網路傳輸,所以這是一種非常低效的實時方案。長輪詢:
長輪詢是對定時輪詢的改進和提高,目地是為了降低無效的網路傳輸。當伺服器端沒有資料更新的時候,連線會保持一段時間週期直到資料或狀態改變或者時間過期,通過這種機制來減少無效的客戶端和伺服器間的互動。當然,如果服務端的資料變更非常頻繁的話,這種機制和定時輪詢比較起來沒有本質上的效能的提高。流:
流技術方案通常就是在客戶端的頁面使用一個隱藏的視窗向服務端發出一個長連線的請求。伺服器端接到這個請求後作出回應並不斷更新連線狀態以保證客戶端和伺服器端的連線不過期。通過這種機制可以將伺服器端的資訊源源不斷地推向客戶端。這種機制在使用者體驗上有一點問題,需要針對不同的瀏覽器設計不同的方案來改進使用者體驗,同時這種機制在併發比較大的情況下,對伺服器端的資源是一個極大的考驗。綜合這幾種方案,您會發現這些目前我們所使用的所謂的實時技術並不是真正的實時技術,它們只是在用Ajax方式來模擬實時的效果,在每次客戶端和伺服器端互動的時候都是一次HTTP的請求和應答的過程,而每一次的HTTP請求和應答都帶有完整的HTTP頭資訊,這就增加了每次傳輸的資料量,而且這些方案中客戶端和伺服器端的程式設計實現都比較複雜,在實際的應用中,為了模擬比較真實的實時效果,開發人員往往需要構造兩個HTTP連線來模擬客戶端和伺服器之間的雙向通訊,一個連線用來處理客戶端到伺服器端的資料傳輸,一個連線用來處理伺服器端到客戶端的資料傳輸,這不可避免地增加了程式設計實現的複雜度,也增加了伺服器端的負載,制約了應用系統的擴充套件性。
WebSocket 的拯救
HTML5 WebSocket設計出來的目的就是要取代輪詢和Comet技術,使客戶端瀏覽器具備像C/S架構下桌面系統的實時通訊能力。瀏覽器通過JavaScript向伺服器發出建立WebSocket連線的請求,連線建立以後,客戶端和伺服器端就可以通過TCP連線直接交換資料。因為WebSocket連線本質上就是一個TCP連線,所以在資料傳輸的穩定性和資料傳輸量的大小方面,和輪詢以及Comet技術比較,具有很大的效能優勢。Websocket.org網站對傳統的輪詢方式和WebSocket呼叫方式作了一個詳細的測試和比較,將一個簡單的Web應用分別用輪詢方式和WebSocket方式來實現,在這裡引用一下他們的測試結果圖:
輪詢和 WebSocket 實現方式的網路負載對比圖
通過這張圖可以清楚的看出,在流量和負載增大的情況下,WebSocket方案相比傳統的Ajax輪詢方案有極大的效能優勢。這也是為什麼我們認為WebSocket是未來實時Web應用的首選方案的原因。
歡迎大家關注我的部落格,關注我的微博,如有疑問,請加qq群:454796847、135430763 共同進步!
相關文章
- 為什麼HTML5裡面我們不需要DTD?HTML
- 為什麼我們需要 VuexVue
- 我們為什麼需要CDP?
- 我們為什麼需要async/await ?AI
- 到底為什麼我們需要 Clickhouse?
- 我們為什麼需要雲原生?
- 我們為什麼需要 lock 檔案
- [譯] 為什麼我們需要 Web 3.0Web
- 什麼是Web workers?為什麼我們需要他Web
- 我們為什麼需要API管理系統?API
- 為什麼我們需要訊息佇列?佇列
- 為什麼我們需要volatile關鍵字?
- 進擊的WebRTC:我們為什麼需要它?Web
- golang拾遺:為什麼我們需要泛型Golang泛型
- 為什麼我們需要配置環境變數變數
- 為什麼我們需要資料庫事務資料庫
- 為什麼我們需要更注重原始碼安全?原始碼
- 為什麼我們需要服務網格Service mesh?
- 我們為什麼需要 DevSecOps 和製品倉庫?dev
- 為什麼我要用GoEasy替代WebSocketGoWeb
- 講道理,React中,我們為什麼需要寫 super(props)?React
- 為什麼我們需要Logstash,Fluentd等日誌攝取器?
- 我們為什麼需要模擬服務機器人?機器人
- 我們需要什麼樣的 ORM 框架ORM框架
- 從爬⾏到奔跑 - 我們為什麼需要單元測試?
- 我們為什麼要用RedisRedis
- 我們為什麼而工作
- 我們為什麼需要獲取器(Getter)和設定器(Setter)?
- 為什麼在大型 Angular 應用裡我們需要使用 ngrxAngular
- 因果迷境:為什麼我們會問“為什麼”?
- 我們需要什麼樣的智慧和AI人才?AI
- 從AIGC到AGI,為什麼我們需要更多的“技術信仰派”?AIGC
- 從服務之間的呼叫來看 我們為什麼需要Dapr
- 為什麼我們需要給 Angular library 建立多重入口 multiple entry pointAngular
- 《後來的我們》,為什麼我們會錯過彼此?
- GC是什麼?為什麼我們要去使用它GC
- 我們為什麼要用英文寫文件?
- 為什麼springcloud值得我們學習?SpringGCCloud
- 為什麼我們不使用GraphQL? - Wundergraph