WEB 即時通訊 4大技術


概述

1996年IETF HTTP工作組發佈了HTT到廣泛應用的協議,相對於互聯網的迅猛發展,它似乎進步地很慢。互聯網從興起到現在,經歷了門戶網站盛行的web1.0時代,而後隨著ajax技術的出現,發展為web應用盛行的web2.0時代,如今又朝著web3.0的方向邁進。反觀http協議,從版本1.0發展到1.1,除了默認長連接之外就是緩存處理、帶寬優化和安全性等方面的不痛不癢的改進。它一直保留著無狀態、請求/響應模式,似乎從來沒意識到這應該有所改變。

好在HTML5的時代已經到來,為Web端即時通訊的實現帶來了WebSocket和SSE(Server-sent Events)兩種技術方案。

Ajax短輪詢:腳本發送的http請求

傳統的web應用要想與服務器交互,必須提交一個表單(form),服務器接收並處理傳來的表單,然後返回全新的頁面,因為前後兩個頁面的數據大部分都是相同的,這個過程傳輸了很多冗餘的數據、浪費了帶寬。於是Ajax技術便應運而生。

Ajax是Asynchronous JavaScript and XML的簡稱,由Jesse James Garrett 首先提出。這種技術開創性地允許瀏覽器腳本(JS)發送http請求。Outlook Web Access小組於98年使用,並很快成為IE4.0的一部分,但是這個技術一直很小眾,直到2005年初,google在他的goole groups、gmail等交互式應用中廣泛使用此種技術,才使得Ajax迅速被大家所接受。

Ajax的出現使客戶端與服務器端傳輸數據少了很多,也快了很多,也滿足了以豐富用戶體驗為特點的web2.0時代 初期發展的需要,但是慢慢地也暴露了他的弊端。比如無法滿足即時通信等富交互式應用的實時更新數據的要求。這種瀏覽器端的小技術畢竟還是基於http協議,http協議要求的請求/響應的模式也是無法改變的,除非http協議本身有所改變。

Comet:一種hack技術

以即時通信為代表的web應用程序對數據的Low Latency要求,傳統的基於輪詢的方式已經無法滿足,而且也會帶來不好的用戶體驗。於是一種基於http長連接的“服務器推”技術便被hack出來。這種技術被命名為Comet,這個術語由Dojo Toolkit 的項目主管Alex Russell在博文Comet: Low Latency Data for the Browser首次提出,並沿用下來。

其實,服務器推很早就存在了,在經典的client/server模型中有廣泛使用,只是瀏覽器太懶了,並沒有對這種技術提供很好的支持。但是Ajax的出現使這種技術在瀏覽器上實現成為可能, google的gmail和gtalk的整合首先使用了這種技術。隨著一些關鍵問題的解決(比如 IE 的加載顯示問題),很快這種技術得到了認可,目前已經有很多成熟的開源Comet框架。

以下是典型的Ajax和Comet數據傳輸方式的對比,區別簡單明瞭。典型的Ajax通信方式也是http協議的經典使用方式,要想取得數據,必須首先發送請求。在Low Latency要求比較高的web應用中,只能增加服務器請求的頻率。Comet則不同,客戶端與服務器端保持一個長連接,只有客戶端需要的數據更新時,服務器才主動將數據推送給客戶端。

WEB 即時通訊 4大技術


Comet的實現主要有兩種方式,基於Ajax的長輪詢(long-polling)方式和基於 Iframe 及 htmlfile 的流(http streaming)方式。

有關Comet技術的詳細介紹文章請參見:《Comet技術詳解:基於HTTP長連接的Web端實時通信技術》、《WEB端即時通訊:HTTP長連接、長輪詢(long polling)詳解》、《WEB端即時通訊:不用WebSocket也一樣能搞定消息的即時性》、《開源Comet服務器iComet:支持百萬併發的Web端即時通訊方案》。

1基於Ajax的長輪詢(long-polling)方式

瀏覽器發出XMLHttpRequest 請求,服務器端接收到請求後,會阻塞請求直到有數據或者超時才返回,瀏覽器JS在處理請求返回信息(超時或有效數據)後再次發出請求,重新建立連接。在此期間服務器端可能已經有新的數據到達,服務器會選擇把數據保存,直到重新建立連接,瀏覽器會把所有數據一次性取回。

WEB 即時通訊 4大技術


2基於 Iframe 及 htmlfile 的流(http streaming)方式

Iframe是html標記,這個標記的src屬性會保持對指定服務器的長連接請求,服務器端則可以不停地返回數據,相對於第一種方式,這種方式跟傳統的服務器推則更接近。

在第一種方式中,瀏覽器在收到數據後會直接調用JS回調函數,但是這種方式該如何響應數據呢?可以通過在返回數據中嵌入JS腳本的方式,如“


但是這種方式有一個明顯的不足之處:IE、Morzilla Firefox 下端的進度欄都會顯示加載沒有完成,而且 IE 上方的圖標會不停的轉動,表示加載正在進行。Google 的天才們使用一個稱為“htmlfile”的 ActiveX 解決了在 IE 中的加載顯示問題,並將這種方法應用到了 gmail+gtalk 產品中。

Websocket:未來的解決方案1

如果說Ajax的出現是互聯網發展的必然,那麼Comet技術的出現則更多透露出一種無奈,僅僅作為一種hack技術,因為沒有更好的解決方案。Comet解決的問題應該由誰來解決才是合理的呢?瀏覽器,html標準,還是http標準?主角應該是誰呢?本質上講,這涉及到數據傳輸方式,http協議應首當其衝,是時候改變一下這個懶惰的協議的請求/響應模式了。

W3C給出了答案,在新一代html標準html5中提供了一種瀏覽器和服務器間進行全雙工通訊的網絡技術Websocket。從Websocket草案得知,Websocket是一個全新的、獨立的協議,基於TCP協議,與http協議兼容、卻不會融入http協議,僅僅作為html5的一部分。於是乎腳本又被賦予了另一種能力:發起websocket請求。這種方式我們應該很熟悉,因為Ajax就是這麼做的,所不同的是,Ajax發起的是http請求而已。

與http協議不同的請求/響應模式不同,Websocket在建立連接之前有一個Handshake(Opening Handshake)過程,在關閉連接前也有一個Handshake(Closing Handshake)過程,建立連接之後,雙方即可雙向通信。

有關WebSocket的詳細介,請參見即時通訊網有關WebSocket的系列文章:《WebSocket詳解(一):初步認識WebSocket技術》、《WebSocket詳解(二):技術原理、代碼演示和應用案例》、《WebSocket詳解(三):深入WebSocket通信協議細節》。

從瀏覽器支持角度來看,WebSocket已經近在眼前,但仍有一段較長的路要走,特別是在中國這個IE6、7、8依然盛行的國家,舊版本瀏覽器的消亡需要很長一段時間,在完全實現瀏覽器全兼容前,Comet技術可能仍然是最好的解決方案。不過,當前也已存在一些比較成熟的封裝方案來解決這種兼容性限制,比如:開源的Socket.io,詳見《Socket.IO介紹:支持WebSocket、用於WEB端的即時通訊的框架》。

SSE:未來的解決方案2

SSE(Server-Sent Event,服務端推送事件)是一種允許服務端向客戶端推送新數據的HTML5技術。與由客戶端每隔幾秒從服務端輪詢拉取新數據相比,這是一種更優的解決方案。

與WebSocket相比,它也能從服務端向客戶端推送數據。那如何決定你是用SSE還是WebSocket呢?概括來說,WebSocket能做的,SSE也能做,反之亦然,但在完成某些任務方面,它們各有千秋。

WebSocket是一種更為複雜的服務端實現技術,但它是真正的雙向傳輸技術,既能從服務端向客戶端推送數據,也能從客戶端向服務端推送數據。

WebSocket和SSE的瀏覽器支持率差不多,大多數主流桌面瀏覽器兩者都支持。在Android 4.3以及更早的版本中,系統默認瀏覽器兩者都不支持,Firefox和Chrome則完全支持;Android 4.4中,系統默認瀏覽器兩者都支持;Safari從5.0開始支持SSE(iOS系統從4.0開始),但直到6.0才正確地支持WebSocket(6.0之前的Safari所實現的WebSocket協議存在安全問題,所以一些主流瀏覽器已經禁用了基於這個協議的實現)。

與WebSocket相比,SSE有一些顯著的優勢。個人認為它最大的優勢就是便利:不需要添加任何新組件,用任何你習慣的後端語言和框架就能繼續使用。你不用為新建虛擬機、弄一個新的IP或新的端口號而勞神,就像在現有網站中新增一個頁面那樣簡單。我喜歡把這稱為既存基礎設施優勢。

SSE的第二個優勢是服務端的簡潔。相對而言,WebSocket則很複雜,不借助輔助類庫基本搞不定(我試過,令人痛苦)。

因為SSE能在現有的HTTP/HTTPS協議上運作,所以它能直接運行於現有的代理服務器和認證技術。而對WebSocket而言,代理服務器需要做一些開發(或其他工作)才能支持,在寫這本書時,很多服務器還沒有(雖然這種狀況會改善)。SSE還有一個優勢:它是一種文本協議,腳本調試非常容易。事實上,在本書中,我們會在開發和測試時用curl,甚至直接在命令行中運行後端腳本。

不過,這就引出了WebSocket相較SSE的一個潛在優勢:WebSocket是二進制協議,而SSE是文本協議(通常使用UTF-8編碼)。當然,我們可以通過SSE連接傳輸二進制數據:在SSE中,只有兩個具有特殊意義的字符,它們是CR和LF,而對它們進行轉碼並不難。但用SSE傳輸二進制數據時數據會變大,如果需要從服務端到客戶端傳輸大量的二進制數據,最好還是用WebSocket。

WebSocket相較SSE最大的優勢在於它是雙向交流的,這意味向服務端發送數據就像從服務端接收數據一樣簡單。用SSE時,一般通過一個獨立的Ajax請求從客戶端向服務端傳送數據。相對於WebSocket,這樣使用Ajax會增加開銷,但也就多一點點而已。如此一來,問題就變成了“什麼時候需要關心這個差異?”如果需要以1次/秒或者更快的頻率向服務端傳輸數據,那應該用WebSocket。0.2次/秒到1次/秒的頻率是一個灰色地帶,用WebSocket和用SSE差別不大;但如果你期望重負載,那就有必要確定基準點。頻率低於0.2次/秒左右時,兩者差別不大。

從服務端向客戶端傳輸數據的性能如何?如果是文本數據而非二進制數據(如前文所提到的),SSE和WebSocket沒什麼區別。它們都用TCP/IP套接字,都是輕量級協議。延遲、帶寬、服務器負載等都沒有區別,除非……呃?除非什麼?

當你在享用SSE的既存基礎設施優勢,並在客戶端和服務端腳本之間設了一個網絡服務器,區別就顯現出來了。一個SSE連接不僅使用一個套接字,還會佔用一個Apache線程或進程,如果用PHP,它會為這個連接專門創建一個PHP新實例。Apache和PHP會使用大量的內存,這會限制服務器所能支持的並行連接數。所以,要做到用SSE在數據傳輸性能上和WebSocket完全一樣,需要寫一個自己的後端服務器,當然,那些在任何情況下都會用自己的服務器並使用Node.js的人,會覺得這有什麼稀奇的。

說一下WebSocket在舊版本瀏覽器上的兼容。當前,大約超過2/3的瀏覽器支持這些新技術,移動端瀏覽器的支持率會低一些。依慣例,每當需要雙向套接字時,就會用到Flash,並且WebSocket的向後兼容通常是用Flash來做,這已經相當複雜了,如果瀏覽器上沒有Flash,情況更糟。概括來說,WebSocket難兼容,SSE易兼容。

有關SSE的詳細介紹文章請參見:《SSE技術詳解:一種全新的HTML5服務器推送事件技術》。

全站即時通訊技術資料分類

[1] 網絡編程基礎資料:

《TCP/IP詳解 - 第11章·UDP:用戶數據報協議》

《TCP/IP詳解 - 第17章·TCP:傳輸控制協議》

《TCP/IP詳解 - 第18章·TCP連接的建立與終止》

《TCP/IP詳解 - 第21章·TCP的超時與重傳》

《理論經典:TCP協議的3次握手與4次揮手過程詳解》

《理論聯繫實際:Wireshark抓包分析TCP 3次握手、4次揮手過程》

《計算機網絡通訊協議關係圖(中文珍藏版)》

《NAT詳解:基本原理、穿越技術(P2P打洞)、端口老化等》

《UDP中一個包的大小最大能多大?》

《Java新一代網絡編程模型AIO原理及Linux系統AIO介紹》

《NIO框架入門(三):iOS與MINA2、Netty4的跨平臺UDP雙向通信實戰》

《NIO框架入門(四):Android與MINA2、Netty4的跨平臺UDP雙向通信實戰》

>> 更多同類文章 ……

[2] 有關IM/推送的通信格式、協議的選擇:

《為什麼QQ用的是UDP協議而不是TCP協議?》

《移動端即時通訊協議選擇:UDP還是TCP?》

《如何選擇即時通訊應用的數據傳輸格式》

《強列建議將Protobuf作為你的即時通訊應用數據傳輸格式》

《移動端IM開發需要面對的技術問題(含通信協議選擇)》

《簡述移動端IM開發的那些坑:架構設計、通信協議和客戶端》

《理論聯繫實際:一套典型的IM通信協議設計詳解》

《58到家實時消息系統的協議設計等技術實踐分享》

>> 更多同類文章 ……

[3] 有關IM/推送的心跳保活處理:

《Android進程保活詳解:一篇文章解決你的所有疑問》

《Android端消息推送總結:實現原理、心跳保活、遇到的問題等》

《為何基於TCP協議的移動端IM仍然需要心跳保活機制?》

《微信團隊原創分享:Android版微信後臺保活實戰分享(進程保活篇)》

《微信團隊原創分享:Android版微信後臺保活實戰分享(網絡保活篇)》

《移動端IM實踐:實現Android版微信的智能心跳機制》

《移動端IM實踐:WhatsApp、Line、微信的心跳策略分析》

>> 更多同類文章 ……

[4] 有關WEB端即時通訊開發:

《新手入門貼:史上最全Web端即時通訊技術原理詳解》

《Web端即時通訊技術盤點:短輪詢、Comet、Websocket、SSE》

《SSE技術詳解:一種全新的HTML5服務器推送事件技術》

《Comet技術詳解:基於HTTP長連接的Web端實時通信技術》

《WebSocket詳解(一):初步認識WebSocket技術》

《socket.io實現消息推送的一點實踐及思路》

>> 更多同類文章 ……

[5] 有關IM架構設計:

《淺談IM系統的架構設計》

《簡述移動端IM開發的那些坑:架構設計、通信協議和客戶端》

《一套原創分佈式即時通訊(IM)系統理論架構方案》

《從零到卓越:京東客服即時通訊系統的技術架構演進歷程》

《蘑菇街即時通訊/IM服務器開發之架構選擇》

《騰訊QQ1.4億在線用戶的技術挑戰和架構演進之路PPT》

《微信技術總監談架構:微信之道——大道至簡(演講全文)》

《如何解讀《微信技術總監談架構:微信之道——大道至簡》》

《快速裂變:見證微信強大後臺架構從0到1的演進歷程(一)》

《17年的實踐:騰訊海量產品的技術方法論》

>> 更多同類文章 ……

[6] 有關IM安全的文章:

《即時通訊安全篇(一):正確地理解和使用Android端加密算法》

《即時通訊安全篇(二):探討組合加密算法在IM中的應用》

《即時通訊安全篇(三):常用加解密算法與通訊安全講解》

《即時通訊安全篇(四):實例分析Android中密鑰硬編碼的風險》

《傳輸層安全協議SSL/TLS的Java平臺實現簡介和Demo演示》

《理論聯繫實際:一套典型的IM通信協議設計詳解(含安全層設計)》

《微信新一代通信安全解決方案:基於TLS1.3的MMTLS詳解》

《來自阿里OpenIM:打造安全可靠即時通訊服務的技術實踐分享》

>> 更多同類文章 ……

[7] 有關實時音視頻開發:

《即時通訊音視頻開發(一):視頻編解碼之理論概述》

《即時通訊音視頻開發(二):視頻編解碼之數字視頻介紹》

《即時通訊音視頻開發(三):視頻編解碼之編碼基礎》

《即時通訊音視頻開發(四):視頻編解碼之預測技術介紹》

《即時通訊音視頻開發(五):認識主流視頻編碼技術H.264》

《即時通訊音視頻開發(六):如何開始音頻編解碼技術的學習》

《即時通訊音視頻開發(七):音頻基礎及編碼原理入門》

《即時通訊音視頻開發(八):常見的實時語音通訊編碼標準》

《即時通訊音視頻開發(九):實時語音通訊的迴音及迴音消除概述》

《即時通訊音視頻開發(十):實時語音通訊的迴音消除技術詳解》

《即時通訊音視頻開發(十一):實時語音通訊丟包補償技術詳解》

《即時通訊音視頻開發(十二):多人實時音視頻聊天架構探討》

《即時通訊音視頻開發(十三):實時視頻編碼H.264的特點與優勢》

《即時通訊音視頻開發(十四):實時音視頻數據傳輸協議介紹》

《即時通訊音視頻開發(十五):聊聊P2P與實時音視頻的應用情況》

《即時通訊音視頻開發(十六):移動端實時音視頻開發的幾個建議》

《即時通訊音視頻開發(十七):視頻編碼H.264、V8的前世今生》

《簡述開源實時音視頻技術WebRTC的優缺點》

《良心分享:WebRTC 零基礎開發者教程(中文)》

>> 更多同類文章 ……

[8] IM開發綜合文章:

《移動端IM開發需要面對的技術問題》

《開發IM是自己設計協議用字節流好還是字符流好?》

《請問有人知道語音留言聊天的主流實現方式嗎?》

《IM系統中如何保證消息的可靠投遞(即QoS機制)》

《談談移動端 IM 開發中登錄請求的優化》

《完全自已開發的IM該如何設計“失敗重試”機制?》

《微信對網絡影響的技術試驗及分析(論文全文)》

《即時通訊系統的原理、技術和應用(技術論文)》

《開源IM工程“蘑菇街TeamTalk”的現狀:一場有始無終的開源秀》

>> 更多同類文章 ……

[9] 開源移動端IM技術框架資料:

《開源移動端IM技術框架MobileIMSDK:快速入門》

《開源移動端IM技術框架MobileIMSDK:常見問題解答》

《開源移動端IM技術框架MobileIMSDK:壓力測試報告》

《開源移動端IM技術框架MobileIMSDK:Android版Demo使用幫助》

《開源移動端IM技術框架MobileIMSDK:Java版Demo使用幫助》

《開源移動端IM技術框架MobileIMSDK:iOS版Demo使用幫助》

《開源移動端IM技術框架MobileIMSDK:Android客戶端開發指南》

《開源移動端IM技術框架MobileIMSDK:Java客戶端開發指南》

《開源移動端IM技術框架MobileIMSDK:iOS客戶端開發指南》

《開源移動端IM技術框架MobileIMSDK:Server端開發指南》

>> 更多同類文章 ……

[10] 有關推送技術的文章:

《iOS的推送服務APNs詳解:設計思路、技術原理及缺陷等》

《Android端消息推送總結:實現原理、心跳保活、遇到的問題等》

《掃盲貼:認識MQTT通信協議》

《一個基於MQTT通信協議的完整Android推送Demo》

《求教android消息推送:GCM、XMPP、MQTT三種方案的優劣》

《移動端實時消息推送技術淺析》

《掃盲貼:淺談iOS和Android後臺實時消息推送的原理和區別》

《絕對乾貨:基於Netty實現海量接入的推送服務技術要點》

《移動端IM實踐:谷歌消息推送服務(GCM)研究(來自微信)》

《為何微信、QQ這樣的IM工具不使用GCM服務推送消息?》

>> 更多同類文章 ……

[11] 更多即時通訊技術好文分類:

http://www.52im.net/forum.php?mod=collection&op=all

16 條評論

WEB 即時通訊 4大技術


2樓

IMDeveloper LV.5

WEB 即時通訊 4大技術

WEB 即時通訊 4大技術

WEB 即時通訊 4大技術


3 年前

總結的很好,再也不用糾結了該選啥了,一目瞭然

簽名: 國慶長假還沒有緩過來,請讓我靜一靜,產品狗死遠點...

WEB 即時通訊 4大技術


3樓

什麼狗屁雲 LV.3

WEB 即時通訊 4大技術


3 年前

不錯不錯,秒懂了

簽名: 該會員沒有填寫今日想說內容.

WEB 即時通訊 4大技術


4樓

mo_mean LV.1

3 年前

受教了·

WEB 即時通訊 4大技術


5樓

JackJiang LV.9

WEB 即時通訊 4大技術

WEB 即時通訊 4大技術

WEB 即時通訊 4大技術

樓主

3 年前

引用另一個網友的評論:

PHP即時通訊國人就搞了可用的兩套方案,一套是WorkerMan,一套是Swoole.

國人純PHP開發的高性能聊天室框架WorkerMan:

http://www.workerman.net/workerman-chat

http://doc.workerman.net/start/environment.html

前端:HTML5 WebSocket

後端:PHP-CLI (不依賴Nginx/Apache)

WorkerMan用到了若干PHP進程控制PECL擴展(不支持Windows):

pcntl: 進程創建,信號控制,定時器,進程狀態監控

posix: 守護進程化,用戶組控制

sysvshm: 共享內存,進程間通信

sysvmsg: 消息隊列,進程間通信

libevent: 讓PHP可以使用系統epoll/kqueue等高級事件處理機制,能夠顯著提高WorkerMan在高併發連接時CPU利用率.

proctitle: 更改進程的名稱

PECL擴展Swoole支持使用PHP來編寫高性能的socket應用:

pecl remote-info swoole

http://www.swoole.com

http://git.oschina.net/matyhtf/swoole/blob/master/examples

PHPWebIM是Swoole官方基於PHP Swoole擴展和Swoole Framework開發的WebSocket網頁即時聊天工具.

PHPWebIM支持WebSocket+Comet兩種協議,可用於所有種類的瀏覽器包括IE.

https://github.com/matyhtf/PHPWebIM

Demo: http://webim.swoole.com

簽名: 《微信支付代碼重構帶來的移動端軟件架構上的思考》http://www.52im.net/thread-2958-1-1.html

上一頁

第1頁

第2頁

第3頁

第4頁

第1頁

下一頁

我也要說兩句

16

評論

12

收藏

2

© 即時通訊網 - 即時通訊開發者社區



分享到:


相關文章: