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