簡體   English   中英

我對HTTP輪詢,長輪詢,HTTP流和WebSockets的理解

[英]My Understanding of HTTP Polling, Long Polling, HTTP Streaming and WebSockets

我在SO和網上看了很多關於我的問題標題中的關鍵詞的帖子,並從中學到了很多。 我讀到的一些問題與具體的實施挑戰有關,而其他問題則側重於一般概念。 我只是想確保我理解為什么技術X是在技術Y上發明的所有概念和原因等等。 所以這里:

Http Polling:基本上是AJAX,使用XmlHttpRequest。

Http Long Polling: AJAX但服務器保持響應,除非服務器有更新,一旦服務器有更新,它發送它然后客戶端可以發送另一個請求。 缺點是需要來回發送額外的頭數據會導致額外的開銷。

Http Streaming:類似於長輪詢,但是服務器使用帶有“Transfer Encoding:chunked”的標頭進行響應,因此每次服務器發送一些數據時我們都不需要發起新的請求(因此節省了額外的頭部開銷)。 這里的缺點是我們必須“理解”並找出數據的結構,以區分服務器發送的多個塊。

Java Applet,Flash,Silverlight:它們提供了通過tcp / ip連接到套接字服務器的能力,但由於它們是插件,開發人員不希望依賴它們。

WebSockets:它們是新的API,它試圖通過以下方式解決上述方法的缺點:

  • 與Java Applet,Flash或Silverlight等插件相比,WebSockets的唯一優勢是WebSockets本身內置於瀏覽器中,不依賴於插件。
  • WebSockets優於http流的唯一優勢是您不必努力“理解”並解析收到的數據。
  • WebSockets優於長輪詢的唯一優勢是消除額外的標頭大小以及為請求打開和關閉套接字連接。

我還缺少其他重大差異嗎? 如果我重新詢問或將SO上已有的許多問題合並到一個問題中,我很抱歉,但我只是想從SO和網絡上關於這些概念的所有信息中完全理解。

謝謝!

與您確定的差異相比,存在更多差異。

雙面打印/方向:

  • 單向:HTTP輪詢,長輪詢,流式傳輸。
  • Bi-direcitonal:WebSockets,插件網絡

為了增加延遲(近似值):

  • 的WebSockets
  • 插件網絡
  • HTTP流媒體
  • HTTP長輪詢
  • HTTP輪詢

CORS(跨域支持):

  • WebSockets:是的
  • 插件網絡:通過策略請求Flash(不確定其他人)
  • HTTP *(最近的一些支持)

本機二進制數據(類型化數組,blob):

  • WebSockets:是的
  • 插件網絡:不使用Flash(需要跨ExternalInterface進行URL編碼)
  • HTTP *:最近提出啟用二進制類型支持的提議

帶寬效率下降:

  • 插件網絡:除初始策略請求外,Flash套接字是原始的
  • WebSockets:連接設置握手和每幀幾個字節
  • HTTP流(重新使用服務器連接)
  • HTTP long-poll:每條消息的連接
  • HTTP輪詢:每條消息的連接+沒有數據消息

移動設備支持:

  • WebSocket:iOS 4.2及更高版本。 一些Android通過Flash模擬或使用Android for AndroidGoogle Chrome for Android ,它們都提供原生WebSocket支持。
  • 插件網絡:一些Android。 不在iOS上
  • HTTP *:大多是的

Javascript使用復雜度(從最簡單到最復雜)。 無可否認,復雜性措施有點主觀。

  • 的WebSockets
  • HTTP輪詢
  • 插件網絡
  • HTTP長輪詢,流式傳輸

另請注意,有一個W3C提議用於標准化稱為服務器發送事件的 HTTP流。 它目前還處於早期發展階段,旨在提供標准的Javascript API,其簡單性與WebSockets相當。

來自其他人的一些很好的答案涵蓋了很多方面。 這里有點多余。

與Java Applet,Flash或Silverlight等插件相比,WebSockets的唯一優勢是WebSockets本身內置於瀏覽器中,不依賴於插件。

如果這意味着您可以使用Java Applet,Flash或Silverlight來建立套接字連接,那么是的,這是可能的。 但是,由於這些限制,您不會經常在現實世界中部署。

例如,中介可以並且確實關閉該流量。 WebSocket標准旨在與現有的HTTP基礎架構兼容,因此不太容易受到防火牆和代理等中介的干擾。

此外,WebSocket可以使用端口80和443而無需專用端口,這要歸功於協議設計與現有HTTP基礎架構盡可能兼容。

那些套接字替代品(Java,Flash和Silverlight)很難在跨源體系結構中安全使用。 因此,經常試圖使用它們來源的人會容忍不安全感,而不是努力安全地做到這一點。

他們還可能需要打開額外的“非標准”端口(管理員不願意這樣做)或需要管理的策略文件。

簡而言之,使用Java,Flash或Silverlight進行套接字連接是有問題的,您不會經常在嚴肅的架構中看到它。 Flash和Java已經擁有這種能力至少10年,但它並不普遍。

WebSocket標准能夠以一種全新的方法開始,並考慮到這些限制,並希望從中吸取教訓。

當無法建立WebSocket連接時(例如在舊瀏覽器中運行或中間人干擾時),某些WebSocket實現使用Flash(或可能是Silverlight和/或Java)作為其后備。

雖然針對這些情況的某種回退策略是明智的,甚至是必要的,但大多數使用Flash等的人都會遇到上述缺點。 它不一定是這樣 - 有使用Flash,Silverlight等實現安全的跨源連接的解決方法 - 但是大多數實現都不會這樣做,因為它並不容易。

例如,如果您依賴WebSocket進行跨源連接,則可以正常工作。 但是,如果您在舊的瀏覽器或受干擾的防火牆/代理中運行並依賴Flash,比如說,作為您的后備,您將發現難以進行相同的跨源連接。 當然,除非你不關心安全性。

這意味着很難有一個統一的架構適用於本機和非本機連接,除非你准備投入相當多的工作或者使用已經做得很好的框架。 在理想的架構中,您不會注意到連接是否是本機的; 您的安全設置在兩種情況下都有效; 您的群集設置仍然有效; 你的容量規划仍然存在; 等等。

WebSockets優於http流的唯一優勢是您不必努力“理解”並解析收到的數據。

它並不像打開HTTP流那樣簡單,只需數據流動數分鍾,數小時或更長時間即可。 不同的客戶端行為不同,您必須管理它。 例如,某些客戶端將緩沖數據,並且在滿足某個閾值之前不會將其釋放到應用程序。 更糟糕的是,在連接關閉之前,有些人不會將數據傳遞給應用程序。

因此,如果您向客戶端發送多條消息,則客戶端應用程序可能無法接收數據,直到收到50條消息的數據為止。 那不是太實時。

雖然當WebSocket不可用時,HTTP流是一種可行的替代方案,但它並不是萬能葯。 在現實世界的條件下,需要很好地理解在Web的荒地中以健壯的方式工作。

我還缺少其他重大差異嗎?

還有一件事沒有提到,所以我會提出來的。

WebSocket協議旨在成為更高級別協議的傳輸層。 雖然您可以直接通過WebSocket連接發送JSON消息或什么不是,但它也可以攜帶標准或自定義協議。

例如,您可以通過WebSocket執行AMQP或XMPP,就像人們已經做過的那樣。 因此,客戶端可以從AMQP代理接收消息,就好像它直接連接到代理本身(在某些情況下它是)。

或者,如果您的現有服務器具有某些自定義協議,則可以通過WebSocket傳輸該服務器,從而將該后端服務器擴展到Web。 通常,已鎖定在企業中的現有應用程序可以使用WebSocket擴展其范圍,而無需更改任何后端基礎結構。

(當然,您希望能夠安全地執行所有操作,因此請與供應商或WebSocket提供商聯系。)

有些人將WebSocket稱為Web的TCP。 因為就像TCP傳輸更高級別的協議一樣,WebSocket也是如此,但它與Web基礎架構兼容。

因此,盡管通過WebSocket直接發送JSON(或其他)消息總是可行的,但也應考慮現有協議。 因為對於你想要做的很多事情,可能已經考慮過這樣做的協議。

如果我重新詢問或將SO上已有的許多問題合並到一個問題中,我很抱歉,但我只是想從SO和網絡上關於這些概念的所有信息中完全理解。

這是一個很好的問題,答案都非常豐富!

如果我可能會問另外一件事:我在某篇文章中遇到過這樣的文章:http流也可能被代理緩存,而websockets則不會。 那是什么意思?

(StackOverflow限制了評論響應的大小,所以我必須在這里回答而不是內聯。)

那是個很好的觀點。 要理解這一點,請考慮一下傳統的HTTP場景......想象一下,瀏覽器打開了一個網頁,所以它請求http://example.com 服務器使用包含頁面HTML的HTTP進行響應。 然后瀏覽器看到頁面中有資源,因此它開始請求CSS文件,JavaScript文件和圖像。 它們都是靜態文件,對於請求它們的所有客戶端都是相同的。

一些代理將緩存靜態資源,以便來自其他客戶端的后續請求可以從代理獲取這些靜態資源,而不必一直返回到中央Web服務器來獲取它們。 這是緩存,從中央服務卸載請求和處理是一個很好的策略。

因此,客戶#1請求http://example.com/images/logo.gif 該請求一直通過代理到中央Web服務器,后者提供了logo.gif。 當logo.gif通過代理時,代理將保存該圖像並將其與地址http://example.com/images/logo.gif相關聯。

當客戶端#2出現並請求http://example.com/images/logo.gif時 ,代理可以返回圖像,並且不需要回復到中心的Web服務器。 這樣可以更快地響應最終用戶,這總是很好,但這也意味着中心負載較少。 這可以轉化為降低硬件成本,降低網絡成本等。所以這是一件好事。

在Web服務器上更新logo.gif時會出現問題。 代理將繼續為舊圖像提供服務而不知道有新圖像。 這會導致整個過期到期,因此代理只會在“過期”之前將圖像緩存一小段時間,然后下一個請求通過代理到達Web服務器,然后刷新代理的緩存。 還有更先進的解決方案,中央服務器可以推送到已知的緩存,等等,事情可以變得非常復雜。

這與你的問題有什么關系?

您詢問了有關服務器將HTTP流式傳輸到客戶端的HTTP流式傳輸。 但是流式HTTP就像普通的HTTP一樣,除了你不停止發送數據。 如果Web服務器提供圖像,它會將HTTP發送到最終結束的客戶端:您已發送整個圖像。 如果你想發送數據,它是完全一樣的,但是服務器只是發送了很長時間(比如它是一個巨大的巨大圖像),甚至從未完成。

從代理的角度來看,它無法區分HTTP作為靜態資源(如圖像)或數據來自HTTP流。 在這兩種情況下,客戶端都發出了服務器的請求。 代理記住了該請求以及響應。 下次請求進入時,代理會提供相同的響應。

因此,如果您的客戶提出股票價格請求,並獲得響應,則下一個客戶端可以發出相同的請求並獲取緩存數據。 可能不是你想要的! 如果您要求股票價格,您需要最新數據,對吧?

所以這是一個問題。

有一些技巧和變通方法來處理這樣的問題,這是事實。 顯然,你可以讓HTTP流式傳輸工作,因為它現在正在使用。 這對最終用戶來說都是透明的,但是開發和維護這些架構的人必須跳過籃球並付出代價。 它導致過於復雜的架構,這意味着更多的維護,更多的硬件,更復雜,更多的成本。 這也意味着開發人員在關注應用程序,GUI和業務邏輯時,往往不得不關心他們不應該關注的事情 - 他們不應該關注底層的溝通。

HTTP將客戶端與服務器的連接數限制為2(盡管可以通過使用子域來緩解這種情況),並且已知IE已經急切地強制執行此操作。 Firefox和Chrome允許更多(雖然我不記得我的頭腦究竟有多少)。 這似乎不是一個大問題,但如果您經常使用1個連接進行實時更新,則所有其他請求都必須通過其他HTTP連接進行瓶頸。 而且客戶端有更多開放連接的問題會給服務器帶來更多負擔。

WebSockets是基於TCP的協議,因此不受此HTTP級別連接限制(但當然,瀏覽器支持不統一)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM