WebSockets與SSE大對決:誰才是實時通信的王者?
當前位置:點晴教程→知識管理交流
→『 技術文檔交流 』
在今天的博文中,我想深入探討服務器發(fā)送事件(簡稱SSE)和WebSockets。這兩種方法都是經過實戰(zhàn)考驗的數(shù)據(jù)交換方式。 我將首先簡要介紹這兩種工具的特性——它們是什么以及提供什么功能。然后,我會根據(jù)八個類別對它們進行比較,我認為這些類別對于現(xiàn)代系統(tǒng)來說最為關鍵。 與我之前比較REST和qRPC不同,我不會在每個類別中宣布任何勝者或授予分數(shù)。相反,在“總結”段落中,你會找到一個類似TL;DR的表格。該表格包含在上述領域中兩種技術的關鍵差異。 與REST不同,SSE和WebSockets都更專注于特定的用例。在這種情況下,這兩個概念的主要關注點是提供一個“實時”通信媒介。由于它們的特定關注點,它們不如REST流行,REST是一種更通用的、一刀切的工具。 不過,SSE和WebSockets都提供了一組有趣的可能性,為經典的REST方法解決復雜問題提供了輕微的更新。在我看來,最好了解它們并在我們的工具箱中為它們找到一席之地,因為有一天它們可能會派上用場。當你需要“實時”更新或你的應用程序需要更推送導向的方法時,它們可以為你提供一個更簡單的解決方案。 簡而言之,它是一種通信協(xié)議,通過使用一個持久的TCP連接在服務器和客戶端之間提供雙向通信。由于這一特性,我們不必不斷從服務器拉取新數(shù)據(jù)。相反,數(shù)據(jù)在相關方之間“實時”交換。每個消息要么是二進制數(shù)據(jù),要么是Unicode文本。 該協(xié)議于2011年由IETF以RFC 6455的形式標準化。WebSocket協(xié)議與HTTP不同,但兩者都位于OSI模型的第七層,并依賴第四層的TCP。 該協(xié)議有一套獨特的前綴,類似于HTTP的http和https前綴: 此外,從安全站點(https)不應打開非安全的WebSocket連接(ws)。類似地,從非安全站點(http)不應打開安全的WebSocket連接(wss)。 另一方面,WebSocket按設計在HTTP端口443和80上工作,并支持HTTP概念,如代理和中間件。此外,WebSocket握手使用HTTP升級頭來將協(xié)議從HTTP升級到WebSocket。 WebSocket作為一個協(xié)議的最大缺點是安全性。WebSocket不受同源策略的限制,這可能使類似CSRF的攻擊更容易。 SSE是一種允許網絡服務器向網頁發(fā)送更新的技術。它是HTML 5規(guī)范的一部分,與WebSockets類似,使用一個持久的HTTP連接來“實時”發(fā)送數(shù)據(jù)。在概念層面上,它是一種相當古老的技術,其理論背景可以追溯到2004年。2006年,Opera團隊首次嘗試實現(xiàn)SSE。 SSE得到了大多數(shù)現(xiàn)代瀏覽器的支持——Microsoft Edge于2020年1月添加了SSE支持。它還可以充分利用HTTP/2,這實際上消除了SSE的一個最大問題,即實際上消除了HTTP/1.1所施加的連接限制。 根據(jù)規(guī)范,服務器發(fā)送事件有兩個基本構建塊: 根據(jù)規(guī)范,事件可以攜帶任意文本數(shù)據(jù),一個可選的ID,并由換行符分隔。它們甚至有其獨特的MIME類型:text/event-stream。 此外,SSE提供了兩個非常有趣的特性: 可能是這兩種技術之間最大的區(qū)別在于它們的通信方式。 我會在接下來的段落中描述所有這些領域以及更多內容。此外,在所有情況下使用WebSocket可能是一個重大過度,基于SSE的解決方案可能更簡單易行。 這里出現(xiàn)了這兩種技術之間的另一個重大區(qū)別。 在SSE的情況下,使用HTTP/2解決了SSE的一個主要問題——最大并行連接限制。HTTP/1.1根據(jù)其規(guī)范限制并行連接的數(shù)量。 這種行為可能導致一個稱為頭部阻塞的問題。HTTP/2通過引入多路復用解決了這個問題,從而在應用層解決了頭部阻塞問題。然而,TCP級別的頭部阻塞仍然可能發(fā)生。 至于WebSocket協(xié)議,我在上面幾行中已經詳細提及。在這里,我只會重申最重要的幾點。該協(xié)議與經典的HTTP有些不同,盡管使用HTTP升級頭來初始化WebSocket連接并有效地更改通信協(xié)議。 盡管如此,它還以TCP協(xié)議為基礎,并且與HTTP完全兼容。WebSocket協(xié)議最大的缺點是其安全性。 一般來說,設置基于SSE的集成比其WebSocket對應物更簡單。其背后最重要的原因是特定技術所利用的通信性質。 SSE的單向通信方式及其推送模型在概念層面上使其更簡單。結合自動重連和流連續(xù)性支持,SSE開箱即用,減少了我們需要處理的事情的數(shù)量。 在WebSocket的情況下,事情變得有點復雜。首先,我們需要處理從HTTP到WebSocket協(xié)議的連接升級。盡管這是最簡單的事情之一,但仍然是我們需要記住的另一件事。 第二個問題是WebSocket的雙向性質。我們必須管理特定連接的狀態(tài),并處理在處理消息時發(fā)生的所有可能的異常。例如,如果服務器端處理其中一個消息時拋出異常,我們該怎么辦? 接下來是處理重連的問題,這在WebSocket的情況下需要我們自己處理。 還存在影響這兩種技術的問題——長連接。 這兩種技術都需要維護長連接以發(fā)送持續(xù)的事件流。 在大規(guī)模管理這些連接可能是一個挑戰(zhàn),因為我們可能很快耗盡資源。此外,它們可能需要特殊配置,如延長超時時間,并且更容易受到任何網絡連接問題的影響。 對于SSE來說,安全性沒有什么特別之處,因為它使用HTTP協(xié)議作為傳輸介質。所有標準的HTTP優(yōu)點和缺點都適用于SSE,非常簡單。 另一方面,安全性是WebSocket協(xié)議作為一個整體最大的缺點之一。首先,沒有同源策略,因此我們可以通過WebSocket連接到任何地方,沒有任何限制。 甚至有一種專門針對這種漏洞的攻擊類型,即跨源WebSocket劫持。如果你想要深入了解更多關于同源策略和WebSocket的內容,這里有一篇文章可能會引起你的興趣。除此之外,WebSocket協(xié)議本身沒有特定的安全漏洞。 我會說,在這兩種情況下,所有標準和最佳安全實踐都適用,因此在實現(xiàn)解決方案時要小心謹慎。 我會說,在性能方面,這兩種技術可以說是不相上下。這兩種技術本身都沒有理論性能限制。 然而,我會說SSE在每秒發(fā)送的消息數(shù)量方面可能更快,因為它遵循一種類似“發(fā)送后即忘”的原則。WebSocket還需要處理來自客戶端的響應。 唯一可能影響兩者性能的因素是我們應用程序中使用的底層客戶端及其實現(xiàn)。檢查、閱讀文檔、運行自定義壓力測試,你可能會對所使用的工具或整個系統(tǒng)獲得非常有趣的見解。 消息結構可能是協(xié)議之間另一個最重要的區(qū)別。 正如我在上面提到的,SSE是一種純文本協(xié)議。我們可以發(fā)送不同格式和內容的消息,但最終所有內容都以UTF-8編碼的文本形式結束。不允許復雜的格式或二進制數(shù)據(jù)。 另一方面,WebSocket可以處理文本和二進制消息。這使我們能夠發(fā)送圖像、音頻或只是普通文件。只是要記住,處理文件可能會有顯著的開銷。 在這方面,這兩種技術處于非常相似的階段。無論是SSE還是WebSockets,都缺少用于自動化測試的專用工具。然而,你可以相對容易地使用Postman和集合來實現(xiàn)類似功能。 Postman支持SSE和WebSockets。通過使用Postman集合的一些魔法,你可以準備一組測試來驗證端點的正確性。 對于性能測試,你可以選擇JMeter或Gatling。據(jù)我所知,這兩個工具是整體性能測試中最成熟的工具。當然,它們也支持SSE(JMeter,Gatling)和WebSockets(JMeter,Gatling)。 還有其他工具如sse-perf(僅限SSE),Testable或k6(僅限WebSockets)。 在所有這些工具中,我個人會推薦Gatling或k6。兩者似乎都有最好的用戶體驗,并且最接近生產環(huán)境。 在某種程度上,沒有專門用于為SSE或WebSockets生成文檔的工具。另一方面,有一個名為AsyncAPI的工具可以以這種方式使用,適用于這兩個概念。 不幸的是,OpenAPI似乎不支持SSE或WebSockets。 如我所承諾的,總結將快速而簡單——請參閱下方表格。 我認為上述表格是對主題和整篇文章的一個相當簡潔的總結。 最重要的區(qū)別是通信方向,因為它決定了特定技術的可能用例。這將對選擇一個而不是另一個產生最大的影響。 消息結構在選擇特定通信方式時也可能是一個非常重要的類別。僅允許純文本消息對于服務器發(fā)送事件來說是一個非常顯著的缺點。 閱讀原文:原文鏈接 該文章在 2025/5/29 10:59:07 編輯過 |
關鍵字查詢
相關文章
正在查詢... |