IM通信技術快速入門:短輪詢、長輪詢、SSE、WebSocket
前言
? 哈啰,大家好,我是洛林,對Web端即時通訊技術熟悉的開發者來說,回顧整個網頁端IM的底層通信技術發展,從短輪詢、長輪詢,到后來的SSE以及WebSocket,我們使用的技術越來越先進,使用門檻也越來越低,給大家帶來的網頁端體驗也越來越好。
? 因此,我們很多時候沒有必要盲目追求新技術,而是適合場景的技術才是最好的技術,掌握WebSocket這些主流新技術固然重要,但了解短輪詢、長輪詢等所謂的“老技術”仍然大有裨益,這就是我分享這篇技術的原因。
即時通訊
? 對于IM/消息推送這類即時通訊系統而言,系統的關鍵就是“實時通信”能力。所謂實時通信有以下兩層含義:
1、客戶端可以主動向服務端發送信息。
2、當服務端內容發生變化時,服務端可以實時通知客戶端。
常用技術
? 客戶端輪詢:傳統意義上的短輪詢(Short Polling)
? 服務器端輪詢:長輪詢(Long Polling)
? 單向服務器推送:Server-Sent Events(SSE)
? 全雙工通信:WebSocket
短輪詢(Short Polling)
實現原理
? 客戶端向服務器端發送一個請求,服務器返回數據,然后客戶端根據服務器端返回的數據進行處理。
? 客戶端繼續向服務器端發送請求,繼續重復以上的步驟。(為了減小服務端壓力一般會采用定時輪詢的方式)
短輪詢通信過程
優點
? 實現簡單,不需要額外開發,僅需要定時發起請求,解析響應即可。
缺點
? 不斷的發起請求和關閉請求,性能損耗以及對服務端的壓力較大,且HTTP請求本身本身比較耗費資源。
? 輪詢間隔不好控制。如果實時性要求較高,短輪詢是明顯的短板,但如果設置太長,會導致消息延遲。
長輪詢(Long Polling)
實現原理
? 客戶端發送一個請求,服務器會hold住這個請求。
? 直到監聽的內容有改變,才會返回數據,斷開連接(或者在一定的時間內,請求還得不到返回,就會因為超時自動斷開連接);
? 客戶端繼續發送請求,重復以上步驟。
長輪詢通信過程
改進點
? 長輪詢是基于短輪詢上的改進版本:減少了客戶端發起Http連接的開銷,改成在服務器端主動地去判斷關注的內容是否變化。
基于iframe的長輪詢
? 基于iframe的長輪詢是長輪詢的另一種實現方案。
實現原理
? 在頁面中嵌入一個iframe,地址指向輪詢的服務器地址,然后在父頁面中放置一個執行函數,比如execute(data);
? 當服務器有內容改變時,會向iframe發送一個腳本;
? 通過發送的腳本,主動執行父頁面中的方法,達到推送的效果。
總結
? 基于iframe的長輪詢底層還是長輪詢技術,只是實現方式不同,而且在瀏覽器上會顯示請求未加載完成,圖標會不停旋轉,簡直是強迫癥殺手,個人不是很推薦。
iframe長輪詢
Server-Sent Events(SSE)
? 上面介紹的短輪詢和長輪詢技術,服務器端是無法主動給客戶端推送消息的,都是客戶端主動去請求服務器端獲取最新的數據。而SSE是一種可以主動從服務端推送消息的技術。
? SSE的本質其實就是一個HTTP的長連接,只不過它給客戶端發送的不是一次性的數據包,而是一個stream流,格式為text/event-stream。所以客戶端不會關閉連接,會一直等著服務器發過來的新的數據流。
實現原理
? 客戶端向服務端發起HTTP長連接,服務端返回stream響應流。客戶端收到stream響應流并不會關閉連接而是一直等待服務端發送新的數據流。
圖片
SSE通信過程
瀏覽器對 SSE 的支持情況
瀏覽器對 SSE 的支持情況
SSE vs WebSocket
? SSE 使用 HTTP 協議,現有的服務器軟件都支持。WebSocket 是一個獨立協議。
? SSE 屬于輕量級,使用簡單;WebSocket 協議相對復雜。
? SSE 默認支持斷線重連,WebSocket 需要自己實現。
? SSE 一般只用來傳送文本,二進制數據需要編碼后傳送,WebSocket 默認支持傳送二進制數據。
? SSE 支持自定義發送的消息類型。
總結
? 對于僅需要服務端向客戶端推送數據的場景,我們可以考慮實現更加簡單的 SSE 而不是直接使用 WebSocket。
WebSocket
? WebSocket 是一種網絡傳輸協議,可在單個 TCP 連接上進行全雙工通信,位于 OSI 模型的應用層。
? WebSocket 使得客戶端和服務器之間的數據交換變得更加簡單,允許服務端主動向客戶端推送數據。客戶端和服務器只需要完成一次握手,兩者之間就可以創建持久性的連接,并進行雙向數據傳輸。
實現原理
? 客戶端發送一個 HTTP GET 請求到服務器,請求的路徑是 WebSocket 的路徑(類似 ws://example.com/socket)。請求中包含一些特殊的頭字段,如 Upgrade: websocket 和 Connection: Upgrade,以表明客戶端希望升級連接為 WebSocket。
? 服務器收到這個請求后,會返回一個 HTTP 101 狀態碼(協議切換協議)。同樣在響應頭中包含 Upgrade: websocket 和 Connection: Upgrade,以及一些其他的 WebSocket 特定的頭字段,例如 Sec-WebSocket-Accept,用于驗證握手的合法性。
? 客戶端和服務器之間的連接從普通的 HTTP 連接升級為 WebSocket 連接。之后,客戶端和服務器之間的通信就變成了 WebSocket 幀的傳輸,而不再是普通的 HTTP 請求和響應,客戶端和服務端相互進行通信。
WebSocket通信過程
優點
? 實時性:WebSocket 提供了雙向通信,服務器可以主動向客戶端推送數據,實現實時性非常高,適用于實時聊天、在線協作等應用。
? 減少網絡延遲:與輪詢和長輪詢相比,WebSocket 可以顯著減少網絡延遲,因為不需要在每個請求之間建立和關閉連接。
? 較小的數據傳輸開銷:WebSocket 的數據幀相比于 HTTP 請求報文較小,減少了在每個請求中傳輸的開銷,特別適用于需要頻繁通信的應用。
? 較低的服務器資源占用:由于 WebSocket 的長連接特性,服務器可以處理更多的并發連接,相較于短連接有更低的資源占用。
? 跨域通信:與一些其他跨域通信方法相比,WebSocket 更容易實現跨域通信。
缺點
? 連接狀態保持:長時間保持連接可能會導致服務器和客戶端都需要維護連接狀態,可能增加一些負擔。
? 不適用于所有場景:對于一些請求-響應模式較為簡單的場景,WebSocket 的實時特性可能并不是必要的,使用 HTTP 請求可能更為合適。
? 復雜性:與傳統的 HTTP 請求相比,WebSocket 的實現和管理可能稍顯復雜,尤其是在處理連接狀態、異常等方面。
總結
? 在本文中我們介紹了IM通信技術中的常用四種技術:短輪詢、長輪詢、SSE、WebSocket,使用時可以綜合我們的實際場景選擇合適的通信技術,在復雜的應用場景中,我們可能需要結合不同的技術滿足不同的需求,下面是一些常見的考慮因素:
實時性要求
? 如果實時性要求較低,短輪詢或長輪詢可能足夠;如果需要實時性較高,考慮使用SSE或WebSocket,若僅需要服務端推送,盡可能考慮SSE。
網絡和服務器資源
? 短輪詢和長輪詢可能會產生較多的無效請求,增加帶寬和服務器負擔;SSE和WebSocket相對更高效。
個人簡介
?? 你好,我是 Lorin 洛林,一位 Java 后端技術開發者!座右銘:Technology has the power to make the world a better place.