本文在編寫時參考了博客作者“鹿呦呦”和在線課程“即時消息技術剖析與實戰”的相關資料,一并表示感謝。
1、引言
隨著移動互聯網絡的發展,IM技術的應用已經不僅限于聊天應用本身,它早已融入各種應用形態中,比如:直播中的主播互動、聯網游戲中的玩家互動、外賣/打車應用中的實時位置共享、在線教育應用中的互動白板等。
在這些風格迥異的應用場景下,IM技術所呈現出來的功能形態雖有不同,但“實時性”這個技術特征并無區別。
那么,對于技術門外漢來說,到底什么是IM的“實時性”?該如何理解它?這就是本文想要討論的主題。
區別于強大的原生應用,Web端的IM系統,在很長一段時間內想實現真正的“實時性”,是非常困難的,因為無法直接使用UDP、TCP通信協議,在HTML5中的WebSocket出現之前,Web端幾乎沒有真正意義上的“雙向實時通信”這種技術存在。
正因為如此,理解Web端即時通信技術的演進,也就自然而然能循序漸進地體會到IM系統中的“實時性”了。所以本文將圍繞Web端即時通訊技術,為你展開IM“實時性”這個話題。
友情提示:本系列文章側重于理論概念的講述,篇幅有限,點到即止,如需系統、深入、具體地學習IM技術的方方面面,請從此文入手:《新手入門一篇就夠:從零開發移動端IM》(史詩級文章,適合從入門到放棄)。
學習交流:
- 即時通訊/推送技術開發交流5群:215477170 [推薦]
- 移動端IM開發入門文章:《新手入門一篇就夠:從零開發移動端IM》
- 開源IM框架源碼:https://github.com/JackJiang2011/MobileIMSDK
(本文同步發布于:http://www.52im.net/thread-3143-1-1.html)
2、系列文章目錄
《IM開發快速入門(一):什么是IM系統?》
《IM開發快速入門(二):什么是IM系統的實時性?》(* 本文)
《IM開發快速入門(三):什么是IM系統的可靠性? (稍后發布)》
《IM開發快速入門(四):什么是IM系統的一致性? (稍后發布)》
《IM開發快速入門(五):什么是IM系統的安全性? (稍后發布)》
《IM開發快速入門(六):什么是IM系統的的心跳機制? (稍后發布)》
《IM開發快速入門(七):如何理解并實現IM系統消息未讀數? (稍后發布)》
《IM開發快速入門(八):如何理解并實現IM系統的多端消息漫游? (稍后發布)》
3、短輪詢技術
在早期的Web時代,技術的創造者們無法預見如今各種選進的技術應用形式,他們認為數據只是用來“看”的,也數據的獲取基本就是“請求 -> 響應”這種一問一答形式。包括我們平時瀏覽的各種門戶網站都是采用的“請求響應”模式。
這種依賴于用戶“主動”請求的數據獲取模式,如果想實現IM系統,是無法即時獲得最新的聊天消息的,因為用戶并不知道新消息什么時候到來,而服務端也沒有辦法主動通知用戶。
在這個時期,雖然技術和思路都受當時技術水平的限制,但IM總不能不做吧。
于是,一種被稱為“短輪詢”的數據獲取模式出現了。在“短輪詢”模式下,IM客戶端定時輪詢服務端,以便讓用戶知道是否有新的聊天消息存在。
這種模式下,服務端收到請求后,即刻查詢是否存在新消息,有就返回給客戶端,沒有則返回空并立即關閉連接。
相較于前面用戶需要“手動”去刷新頁面的方式,這種模式只是將用戶的“手動”變為“自動”而已,技術本質并沒有發生任何實質性改變。
短輪詢這種模式,就好比舊時代一個等待重要郵件的人,他需要每天自已跑到郵局,主動去問是否有自己的信件,有就拿回家,如果沒有,則第二天繼續去問。一來一去,非常低效。
技術原理總結如下圖所示:

短輪詢這種模式有好處,也有壞處。
好處是:
- 1)技術簡單,容易實現;
- 2)可維護性強,因為它沒什么復雜的。
壞處是:
- 1)因為無法預知數據是否存在,所以多數請求是無用的,浪費計算資源;
- 2)為了提升實時性,高頻率的請求會加大服務端的性能負載。
總結一下就是,短輪詢這種模式對于IM技術大拿來說,顯的非常low,因為技術實現實在是簡單粗暴。
4、長輪詢技術
正如你所見,用短輪詢技術來保證IM的實時性,確實難說優雅。不過,這難不倒無所不能的程序員,一種被稱為“長輪詢”的數據獲取模式出現了。
從技術上來說,長輪詢實現的IM相較于短輪詢最大的改進在于:短輪詢情況下,服務端不管有沒有新消息,請求結束就會立即斷開連接。而長輪詢時,如果本次請求沒有新消息發生,糨不會馬上斷開連接并返回,而是會將本次連接“掛起”一段時間,如果在這段“掛起”時間內有新的聊天消息出現,就能馬上讀取并立即返回給客戶端,接著結束本次連接。一段時間后又會再次發起請求,如此周而復始。
長輪詢這種模式,拿上節等待郵件的這個例子來說,就好比收信的人每天到郵局去問是否有信件,如果沒有,他不馬上回家,而是在郵局待上一段時間,如果這段時間過去了,還是沒有,就先回家,接著第二天再來。
技術原理總結如下圖所示:
長輪詢的優點是:
- 1)相較于短連詢,一定程度降低了服務端請求負載;
- 2)相較于短連詢,實時性有提升,因為它是主動“等”消息。
長輪詢的缺點是:
- 1)長論詢模式下,連接“掛起”的這段時間內,服務端需要配合開啟單獨的消息查詢線程,仍然存在無用功;
- 2)相較于短連詢模式,在一次長輪詢結束、下次輪詢發起前的窗口期內,仍然存在“實時性”盲區。
實際上,在Web端即時通訊技術里,長輪詢有個專業的術語叫“Comet”,有興趣可以詳細學習《Comet技術詳解:基于HTTP長連接的Web端實時通信技術》。
5、輪詢無法實現真正的“實時性”
對于Web端即時通訊技術來說,上面提到的無論是短輪詢,還是長輪詢,它們都存在“實時性”盲區。
我們回到上兩節介紹的短輪詢和長輪詢技術原理圖。
先看看短輪詢這張圖:
很明顯,短輪詢在每次輪詢結束和下次輪詢開始的間隔期內,是無法感知到新消息的,這也便形成了“實時性盲區”。換句話說,短輪詢技術在“實時性盲區”內,無法做到“實時”。
再來看看長輪詢:
跟短輪詢道理一樣,長輪詢在每次輪詢結束和下次輪詢開始的間隔期,依然會形成“實時性盲區”。
要理解糾結輪詢技術的實時性缺陷,就得了解它們背后的技術——HTTP協議了。
HTTP協議設計的目的,就是為了實現“請求--響應”這種模式的數據交互,也就是眾所周之的“短連接”設計。而無論是短輪詢還是長輪詢,都跳不出HTTP的先天技術邏輯(請求--響應--斷開)。
所以,歸根到底,想要基于HTTP協議來實現IM,要達到真正的“實時性”,是相當勉強的。因為HTTP設計的目的,就是用“短連接”來簡化傳統TCP長連接通信帶來的復雜性,而IM的實時性恰好要用到的又是TCP的長連接特性,所以這就是個悖論。
要真正實現Web端的IM“實時性”,肯定不能強行HTTP上做文章了,我們需要新的技術。
6、WebSocket讓Web端IM真正的“實時性”變成可能
好消息是,HTML5中帶來了WebSocket技術。WebSocket是真正的全雙式雙向通信技術(詳見:《WebSocket從入門到精通,半小時就夠!》)。
下圖上舊式輪詢技術跟WebSocket的對比圖:
從上圖可以看出:
- 1)輪詢技術一問一答,在下一個請求發起之前,存在“實時性”盲區;
- 2)WebSocket一旦建立連接后,數據可以隨時雙向通信(即客戶端可以隨時向服務端發消息,服務端也可以隨時通知客戶端有新消息)。
舉個例子就是:輪詢技術相當于傳統的郵件傳遞方法(你得自已去郵局問有沒有新郵件),而WebSocket相當于現代的電話系統,只要你撥通后,隨時可以實時收聽到對方的聲音,對方也能隨時收聽到你的聲音。完美!
總結一下WebSocket 的優點是:
- 1)真正的實時性:支持客戶端與服務端真正的雙向實時通信;
- 2)大幅降低負載:少了輪詢技術中高頻率無用的請求,可大大降低服務端QPS壓力;
- 3)網絡開銷降低:一次連接,隨時使用,再也不用輪詢技術中每次發起HTTP請求(隨之而來的是每次HTTP的大量冗余協議頭信息等)。
7、本文小結
本文以Web端即時通訊技術的演進為例,從短輪詢到長輪詢,再到WebSocket,理論聯系實際地講解了Web端IM“實時性”的技術變遷,從而幫助讀者理解IM中“實時性”這個最為關鍵的技術特征。
附錄:更多Web端即時通訊資料
《新手入門貼:史上最全Web端即時通訊技術原理詳解》
《Web端即時通訊技術盤點:短輪詢、Comet、Websocket、SSE》
《SSE技術詳解:一種全新的HTML5服務器推送事件技術》
《Comet技術詳解:基于HTTP長連接的Web端實時通信技術》
《新手快速入門:WebSocket簡明教程》
《WebSocket詳解(一):初步認識WebSocket技術》
《WebSocket詳解(二):技術原理、代碼演示和應用案例》
《WebSocket詳解(三):深入WebSocket通信協議細節》
《WebSocket詳解(四):刨根問底HTTP與WebSocket的關系(上篇)》
《WebSocket詳解(五):刨根問底HTTP與WebSocket的關系(下篇)》
《WebSocket詳解(六):刨根問底WebSocket與Socket的關系》
《socket.io實現消息推送的一點實踐及思路》
《LinkedIn的Web端即時通訊實踐:實現單機幾十萬條長連接》
《Web端即時通訊技術的發展與WebSocket、Socket.io的技術實踐》
《Web端即時通訊安全:跨站點WebSocket劫持漏洞詳解(含示例代碼)》
《開源框架Pomelo實踐:搭建Web端高性能分布式IM聊天服務器》
《使用WebSocket和SSE技術實現Web端消息推送》
《詳解Web端通信方式的演進:從Ajax、JSONP 到 SSE、Websocket》
《MobileIMSDK-Web的網絡層框架為何使用的是Socket.io而不是Netty?》
《理論聯系實際:從零理解WebSocket的通信原理、協議格式、安全性》
《微信小程序中如何使用WebSocket實現長連接(含完整源碼)》
《八問WebSocket協議:為你快速解答WebSocket熱門疑問》
《快速了解Electron:新一代基于Web的跨平臺桌面技術》
《一文讀懂前端技術演進:盤點Web前端20年的技術變遷史》
《Web端即時通訊基礎知識補課:一文搞懂跨域的所有問題!》
《Web端即時通訊實踐干貨:如何讓你的WebSocket斷網重連更快速?》
《WebSocket從入門到精通,半小時就夠!》
>> 更多同類文章 ……
本文已同步發布于“即時通訊技術圈”公眾號:

▲ 本文在公眾號上的鏈接是:點此進入,原文鏈接是:http://www.52im.net/thread-3143-1-1.html