前端通訊協議大比拼:WebSockets和HTTP

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在實時應用程序中,毋庸置疑,需要在信息可用時立即從服務器獲取信息。而且,從根本上說,經典的 HTTP ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"請求/響應","attrs":{}}],"attrs":{}},{"type":"text","text":"模式無法勝任這項工作。因爲服務器將保持沉默,無論是否有新數據,除非或直到消費者請求更新。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"隨着開發人員試圖使","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"請求/響應","attrs":{}}],"attrs":{}},{"type":"text","text":"模型適應更動態的實時Web的需求,這種限制導致了各種黑客和變通方法的出現(其中一些變得正式並被廣泛採用)。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所有這些技術和方法,從 ","attrs":{}},{"type":"link","attrs":{"href":"https://zh.wikipedia.org/wiki/Comet_%28web%E6%8A%80%E6%9C%AF%29","title":"","type":null},"content":[{"type":"text","text":"Comet","attrs":{}}]},{"type":"text","text":" 到 HTTP 長輪詢,都有一個共同點:本質上,它們開始創造真正實時(事件驅動)數據交換/通信的錯覺,所以當服務器有一些新數據時,它發送一個響應。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"儘管 HTTP 不是事件驅動的協議,因此也不是真正的實時,但這些方法實際上在特定用例中非常有效,例如 Gmail 聊天。然而,在低延遲應用程序或大規模應用程序中會出現問題,主要是因爲與 HTTP 相關的處理需求。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"也就是說,對於 HTTP,必須不斷請求更新(並獲得響應),這是非常耗費資源的:客戶端建立連接->請求更新->從服務器獲得響應,然後關閉連接。想象一下,這個過程被成千上萬的併發用戶無休止地重複,這對服務器來說是非常繁重的壓力。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"正是這些問題最終促使開發人員 ","attrs":{}},{"type":"link","attrs":{"href":"https://rakutentechnologyconference2017.sched.com/speaker/michael_carter.1x8q89tm","title":"","type":null},"content":[{"type":"text","text":"Michael Carter","attrs":{}}]},{"type":"text","text":" 和 ","attrs":{}},{"type":"link","attrs":{"href":"https://en.wikipedia.org/wiki/Ian_Hickson","title":"","type":null},"content":[{"type":"text","text":"Ian Hickson","attrs":{}}]},{"type":"text","text":" 開發 WebSockets ,本質上是一個構建在設備 TCP/IP 堆棧之上的薄傳輸層。其目的是爲 Web 應用程序提供本質上是 TCP 通信層的東西,它儘可能接近原生,禁止一些抽象,以消除某些基於安全的複雜性和其他問題。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本文將着眼於一些用於繞過實時應用程序中 HTTP ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"請求/響應","attrs":{}}],"attrs":{}},{"type":"text","text":" 模式的限制的技術,每個技術的一些相關問題,以及 WebSockets 如何幫助克服這些問題。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"HTTP","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"HTTP 本質上是","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"客戶端-服務器","attrs":{}}],"attrs":{}},{"type":"text","text":"計算模型中的","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"請求/響應","attrs":{}}],"attrs":{}},{"type":"text","text":"協議,是萬維網的主要通信方式。最初的版本由 ","attrs":{}},{"type":"link","attrs":{"href":"https://zh.wikipedia.org/wiki/%E8%92%82%E5%A7%86%C2%B7%E4%BC%AF%E7%BA%B3%E6%96%AF-%E6%9D%8E","title":"","type":null},"content":[{"type":"text","text":"Tim Berners-Lee","attrs":{}}]},{"type":"text","text":" 在 1989 年作爲應用程序協議提出,非常有限,並迅速修改以支持更廣泛的瀏覽器和服務器功能。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"儘管 HTTP/1.0 不被視爲正式規範或互聯網標準,但這些修改最終在 1996 年被 HTTP 工作組記錄爲 HTTP/1.0(","attrs":{}},{"type":"link","attrs":{"href":"https://datatracker.ietf.org/doc/html/rfc1945","title":"","type":null},"content":[{"type":"text","text":"RFC 1945","attrs":{}}]},{"type":"text","text":")。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"HTTP/1.1","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"HTTP/1.1 是 Web 瀏覽器和服務器中最廣泛支持的版本,它的到來是向前邁出的一大步,因爲它實現了一些非常重要的優化和增強,從持久和管道連接到新的","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"請求/響應頭字段","attrs":{}},{"type":"text","text":"。其中最主要的是兩個標頭,它們是許多改進的基礎,這些改進有助於實現更動態的實時WEB:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Keep-Alive 標頭","attrs":{}}],"attrs":{}},{"type":"text","text":":用於設置主機之間的持久通信。意味着連接可以被重複用於多個請求,這顯着減少了請求延遲,這樣客戶端就不需要在發送第一個請求後重新協商 TCP握手(3次握手)連接。另一個積極的副作用是,由於 TCP 的慢啓動機制,連接會隨着時間的推移而變得更快。在 HTTP/1.1 之前,必須爲每個請求/響應對打開一個新連接。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Upgrade 頭","attrs":{}}],"attrs":{}},{"type":"text","text":":用於將連接升級到增強協議模式(如 WebSockets)。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"HTTP 輪詢","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"HTTP 輪詢代表了經典","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"請求/響應","attrs":{}},{"type":"text","text":"機制的進步,儘管輪詢有多種版本,但只有長輪詢在任何情況下都適用於實時 WEB 程序。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"例如,HTTP 短輪詢使用基於 AJAX 的計時器來確保客戶端設備以固定時間間隔發送服務器請求。但是,服務器仍會立即響應每個請求,在關閉連接之前,要麼提供新數據,要麼在沒有新數據的情況下發送“","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"空","attrs":{}},{"type":"text","text":"”響應。因此,當客戶端需要在新數據可用時立即響應時,這在實時應用程序中真的沒有多大用處。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"正是這種限制導致了 HTTP 長輪詢的發展,它本質上是一種旨在模擬服務器推送功能的技術。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本質上長輪詢是一種技術,其中服務器選擇將客戶端的連接保持儘可能長的時間(通常爲 20 秒),僅在任一數據之後傳遞響應變爲可用或達到超時閾值。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/1a/1a6adbf04f0050ae2c2f0a42202e9e27.jpeg","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"長輪詢的主要優點是,理論上,只要新信息可用,就會立即將其發送給客戶端。然而,不足之處是處理 HTTP 請求帶來的額外開銷。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"HTTP 流媒體","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"HTTP 流是一種推送式數據傳輸技術,它允許 Web 服務器通過無限期保持打開的單個 HTTP 連接向客戶端連續發送數據。本質上,客戶端發出一個 HTTP 請求,服務器推出一個不確定長度的響應。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"然而,雖然 HTTP 流傳輸性能良好、易於使用並且可以替代 WebSockets,但它存在有侷限性。從實時角度來看,主要問題是中介可以中斷連接(無論是通過超時還是僅僅因爲它以“循環方式”服務多個請求),因此並不總是能夠保證實時性。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"HTTP/2.0","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"HTTP/2.0 由 Google 於 2009 年最初宣佈的實驗性協議 SPDY 演變而來。到 2015 年,HTTP 工作組發佈了 HTTP/2.0 作爲建議標準,並以 SPDY 規範爲起點。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"它本質上是一個旨在提高 Web 通信速度的性能更新,主要有以下兩個實用功能:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"多路複用","attrs":{}},{"type":"text","text":":不是以明文格式傳輸數據,而是將數據編碼爲二進制並封裝在幀內,這些幀可以沿着稱爲流的雙向通道進行多路複用,全部通過單個 TCP 連接。這就允許同時發生許多並行的","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"請求/響應","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"服務器推送","attrs":{}},{"type":"text","text":":服務器推送是一種性能特性,它允許服務器在客戶端請求響應之前向符合 HTTP/2 的客戶端發送響應。當服務器知道客戶端需要“推送”響應來完全處理原始請求時,此功能很有用。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"儘管有這些進步,如今由於移動設備的大量使用,互聯網流量的爆炸式增長使得 HTTP/2.0 難以提供流暢、透明的網頁瀏覽體驗,特別是在實時應用程序及其用戶需求日益增長的情況下。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"HTTP/2.0優點","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通過安裝 SSL 證書,所有瀏覽器都支持基於 HTTPS 的 HTTP/2 協議。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"HTTP/2 允許客戶端通過單個 TCP 連接併發發送所有請求,理論上,客戶端可以更快地加載資源。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"TCP 是一種可靠、穩定的連接協議。","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"HTTP/2.0缺點","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"併發請求會增加服務器的負載。HTTP/2 服務器可以大批量接收請求,這可能會導致請求超時。服務器負載峯值的問題可以通過使用負載均衡器或代理服務器來解決,限制轉發請求。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"服務器對 HTTP/2 優先級的支持還不成熟。軟件支持仍在不斷髮展,某些 CDN 或負載均衡器可能無法正確支持優先級。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"HTTP/2 推送功能可能很難正確實現。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"HTTP/2 解決了 HTTP 首尾阻塞問題,但 TCP 級別的阻塞仍然會導致問題。","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"HTTP/3.0","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"HTTP/3.0 是 HTTP 的新迭代,自 2018 年以來一直在開發中,儘管它仍然是標準草案,但一些瀏覽器已經支持它了,如 Chrome。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"HTTP/3 的目標是通過解決 HTTP/2 與傳輸相關的問題,在所有形式的設備上提供快速、可靠和安全的 Web 連接。爲此,它使用稱爲 QUIC 的不同傳輸層網絡協議,該協議運行在用戶數據報協議 (UDP) 上,而不像其他早期版本那樣使用 TCP。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"不過 HTTP/3 已經開始出現一些潛在的問題,例如:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"傳輸層的影響","attrs":{}},{"type":"text","text":":過渡到 HTTP/3 不僅涉及應用層的變化,還涉及底層傳輸層的變化。因此,與其前身相比,採用 HTTP/3 更具挑戰性。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"可靠性和數據完整性問題","attrs":{}},{"type":"text","text":":UDP 一般適用於可以接受丟包的應用,那是因爲 UDP 不保證數據包會按順序到達。事實上,它並不能保證數據包一定會到達,因此,如果數據完整性對應用實例很重要並且使用的是 HTTP/3,則將必須構建相應的機制來確保消息排序和完整的到達。","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"HTTP/3.0優點","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"引入運行在 UDP 上的新(不同)傳輸協議 QUIC 意味着理論上和目前實驗上的延遲減少。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"由於 UDP 不在協議棧中執行錯誤檢查和糾正,因此它適用於不需要這些或在應用程序中執行這些的應用場景。UDP 通常用於時間敏感的應用程序,例如實時系統,它不能等待數據包重新傳輸,因此可以容忍一些丟棄的數據包。","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"HTTP/3.0缺點","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"傳輸層的影響","attrs":{}},{"type":"text","text":":過渡到 HTTP/3 不僅涉及應用層的變化,還涉及底層傳輸層的變化。因此,與其前身相比,採用 HTTP/3 更具挑戰性。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"可靠性問題","attrs":{}},{"type":"text","text":":UDP 應用程序往往缺乏可靠性,必須承認會有一定程度的數據包丟失、重新排序、錯誤或重複。由最終用戶應用程序提供任何必要的握手,例如已收到消息的實時確認。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"HTTP/3 還沒有完全標準化。","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"WebSockets","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"關於 WebSockets 的詳細介紹,可以參閱《","attrs":{}},{"type":"link","attrs":{"href":"https://xie.infoq.cn/article/3702f98ef53dbb5cec3c8995c","title":"","type":null},"content":[{"type":"text","text":"深入學習WebSockets概念和實踐","attrs":{}}]},{"type":"text","text":"》。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/2d/2d58f43cab19cf4bd5292faedd89662c.jpeg","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"WebSockets 允許服務器和客戶端隨時推送消息,而與之前的請求沒有任何關係。使用 WebSockets 的一個顯着優勢是,幾乎每個瀏覽器都支持 WebSockets。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"WebSocket 解決了一些 HTTP 問題:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"雙向協議","attrs":{}},{"type":"text","text":":客戶端/服務器可以向對方發送消息(在 HTTP 中,請求總是由客戶端發起,響應由服務器處理)","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"全雙工通信","attrs":{}},{"type":"text","text":":客戶端和服務器可以同時獨立地相互通信。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"單個 TCP 連接","attrs":{}},{"type":"text","text":": 一開始升級 HTTP 連接後,客戶端和服務器在 WebSocket 連接的整個生命週期都通過相同的 TCP 連接(持久連接)進行通信,很好的節省服務器資源和帶寬。","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"WebSockets優點","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"WebSocket 是一種事件驅動的協議,這意味着可以將其用於真正的實時通信。與 HTTP 不同(必須不斷地請求更新),而使用 websockets,更新在可用時就會立即發送。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"WebSockets 保持單個持久連接打開,同時消除基於 HTTP ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"請求/響應","attrs":{}},{"type":"text","text":"的方法出現的延遲問題。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"WebSockets 通常不使用 XMLHttpRequest,因此,每次需要從服務器獲取更多信息時,都不會發送標頭。這反過來又減少了發送到服務器的數據負載。","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"WebSockets缺點","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"當連接終止時,WebSockets 不會自動恢復,這是應用開發中需要自己實現的機制,也是存在許多客戶端開源庫的原因之一。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"早於 2011 年的瀏覽器無法支持 WebSocket 連接,這個現在可以忽略不計。","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"總結","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通常,在實時、持續通信的上下文中,WebSockets 將是更好的選擇。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"基於 HTTP 的技術往往在服務器上佔用更多資源,而 WebSockets 在服務器上的佔用空間非常小。同時,像長輪詢這樣的方法也需要在服務器和設備之間進行多次跳轉,並且這些網關通常對允許連接保持打開狀態的時間有不同的限制。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果項目中有長連接、不斷更新、實時數據交互的需求,應該首選 WebSockets 來構建。","attrs":{}}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章