即时通讯软件架构
http://nopainnogain.iteye.com/blog/832017
http://blog.csdn.net/realxie/article/details/7270119
http://zoomq.qiniudn.com/ZQScrapBook/ZqSKM/data/20100325150259/index.html
個人理解:TCP是天生的長連接協議,主要看其上的協議
TCP連接一旦建立連接,通信雙方就可以相互發送信息,可以看做是長連接
雖然http也是基于TCP的,但是其在通訊結束之后,瀏覽器就主動斷開連接,所以看起來是 request-response的形式
poll方式
poll方式,也稱為輪循,是大家都比較熟悉的一種數據同步方式,客戶端定期去ping查詢服務器,確定是否有需要的數據。例如,軟件更新模塊,客戶端軟件需要定期去查詢官方網站,判斷當前是否有更新的版本,如果有就提醒用戶進行升級。郵件客戶端,需要定期查詢郵件服務器,查詢是否有新的郵件。RSS閱讀器,也是需要不斷的查詢rss地址的狀態,如果有更新,就將數據拿回來。
當服務器沒有數據的時候,poll方式會浪費大量的帶寬。 為了降低帶寬,通常是采用減低poll的頻率來實現的,這就導致了消息的長延遲,實時性不高。像gmail的POP3郵件檢查間隔從10分鐘到1小時不等。
push方式
poll的問題在于很多情況下,通信信道是單向的。為了解決poll的問題,可以將通信信道設計為雙向的,這樣就可以服務器采用push的方式主動向客戶端進行數據同步了。雙向通信信道設計,考慮到要穿透NAT和防火墻,很多實現采用長連接。例如各種IM的實現:MSN是TCP的長連接,QQ是UDP模仿的長連接,GTALK是HTTP模仿的長鏈接。
push方式,服務器主動向客戶端推送數據。當前實現push方式有兩種方法:
1. 客戶端首先連接到服務器,并維持長連接
2. 服務器能夠直接訪問到客戶端,不需要長連接
在國內NAT和firewall遍地都是的情況下,第2種方法不是很可行,但是對于一些企業應用,這種方法還是不錯的,比如后面提到的pubsubhubbub。
但是push方式,通常需要長連接,對于服務器端其實也是一個不小的壓力,雖然現在C10K問題得到了比較好的解決,但是對于一些大規模互聯網應用來講,用戶數是數以億計的,單單是維持TCP連接,就需要太多的服務器。因此,除了一些實時性要求比較高的應用,現在push方式使用的范圍還不是很廣,例如push方式在IM、服務器監控等領域都有應用。
XMPP
xmpp類似于email系統,將一個消息從一個JID送達到另一個JID。xmpp通常被用作im,那么它是如何實現實時消息傳送的呢。我們接下來討論的BOSH技術就是解決這個問題的。BOSH也就是Bidirectional-streams Over Synchronous HTTP,在HTTP上模擬長連接,gtalk就是用的這種方法。 BOSH技術能夠同時減小網絡帶寬和減小客戶端響應的時間。其方案是對客戶端的請求連接管理器不給于返回直到數據已經就緒,當客戶端收取連接管理器返回的數據會向連接管理器發送下一個請求,于是連接管理器總是保持著一個客戶端的請求,當服務器端數據就緒的時候,可以將數據封裝在請求的響應包中,“推送”給客戶端。 如果雙向連接長時間沒有數據,連接管理器負責給客戶端發送一個空包,空包觸發客戶端發送新的請求,連接管理器通過這種機制判斷連接是否已經中斷,由于BOSH不是輪詢的機制,帶寬消耗比標準的TCP連接大不了多少。
由于大多數的客戶端不支持HTTP的Pipeling(單一的連接上承載并發的請求),于是,客戶端必須從第二條HTTP連接發送消息。當第二條HTTP連接有新的請求發送的時候,連接管理器將第一條連接中的請求返回,即便此時第一條連接中的返回的是空數據包。這樣做的原因是讓客戶端有需要的話可以發送新的請求過來。客戶段同一時間最多只能保持兩條HTTP連接,否則的話,客戶端必須等待舊的請求處理完之后才能發送新的請求
在網絡經常中斷的環境下,BOSH退化成每個數據請求一個新HTTP連接。然而,在通常情況下,網絡環境良好,客戶端可以使用http/1.1,這個時候,一個Session包含兩個TCP長連接,所有的請求都在這兩個長連接上傳輸。基本上任何時候,客戶端通過一條連接能夠推送數據到服務器,與此同時,服務器端可以“推送”數據到客戶端。值得注意的是,這兩條長連接的角色在客戶端每發送一次請求則角色轉換一次。
盡管大多數時間可以隨時推送數據到對端,但是,如果一方剛剛推送完數據,則需要等一個網絡來回的時間才能推送下一個數據。
pubsubhubbub
pubsubhubbub是Google的工程師開發的一種協議,可以在ATOM和RSS更新的時候,訂閱者能實時得到更新,實現一種基于RSS Feed的類似Twitter的實時效果。 PubSubHubbub 協議在供稿網址內容更新后,能接近即時的得到通知(通過webhook回調)。sub(訂閱者)向要訂閱的RSS中指定的hub進行注冊,hub和pub(發布者)之間通過poll和push等方式同步數據,然后hub向已經注冊的sub推送更新后的數據。 這樣,就能夠實時的得到RSS的更新,而且避免了sub不斷輪循pub,節省了帶寬。但是,這有一個缺點,就是hub向sub推送消息,就回到最初我們討論的兩種方法,現在pubsubhubbub中sub大都要求為公網可訪問,但是對于一些企業應用,像google reader,這樣做還是會節省很大帶寬的。
PubSubHubbub 協議概述如下: 1. 一個供稿網址( “主題” )通過<link rel="hub" ...> 標簽在其Atom或RSS的XML文件中聲明其Hub server (樞紐服務器) 。這個 Hub(s) 可以由feed的發布者運行,也可以是一個任何人都可以使用得社區 Hub (community hub)。 2. 一個訂閱者(對某個主題有興趣的服務器) ,首先正常的抓取Atom網址。如果Atom檔案聲明它是 Hub ,訂閱者就可以避免重復查看網址,而是在feed的 Hub 注冊和訂閱更新。 3. 訂閱者通過主題的URL的聲明的 Hub 訂閱這個主題。 4. 當作者更新主題時,Hub 被告知發生了一個更新。 5. 之后 Hub 有效提取 feed 然后同時將新更改后的內容廣播向所有訂閱的用戶。
不管UDP還是TCP,最終登陸成功之后,QQ都會有一個TCP連接來保持在線狀態。這個TCP連接的遠程端口一般是80,采用UDP方式登陸的時候,端口是8000。因此,假如你所在的網絡開放了80端口(80端口是最常用端口。。就是通常訪問Web的端口,禁掉它的話,你的網絡對你來說價值已經不大了),但沒有屏蔽騰訊的服務器IP,恭喜你,你是可以登陸成功QQ的。
二、聊天消息通信。
?
? ??采用UDP協議,通過服務器中轉方式。因此,現在的IP偵探在你僅僅跟對方發送聊天消息的時候是無法獲取到IP的。大家都知道,UDP 協議是不可靠協議,它只管發送,不管對方是否收到的,但它的傳輸很高效。但是,作為聊天軟件,怎么可以采用這樣的不可靠方式來傳輸消息呢?于是,騰訊采用了上層協議來保證可靠傳輸:如果客戶端使用UDP協議發出消息后,服務器收到該包,需要使用UDP協議發回一個應答包。如此來保證消息可以無遺漏傳輸。之所以會發生在客戶端明明看到“消息發送失敗”但對方又收到了這個消息的情況,就是因為客戶端發出的消息服務器已經收到并轉發成功,但客戶端由于網絡原因沒有收到服務器的應答包引起的。
?
三、文件/自定義表情傳送。
?
? ??大家都知道,QQ可以傳送文件,可以發送自定義表情。先說官方表情。官方表情實際發送的是命令字,而沒有發送表情。客戶端收到命令字后,會自動解釋為對應的表情。因此,QQ2008正式版的客戶端發出的新版表情,在2007beta4及以前的版本無法找到相對應的表情,就無法解釋,看到的就會是空白信息,但查聊天記錄就會有[表情]字樣。
? ??自定義表情的傳送是以文件傳輸方式進行的。
? ??下面說文件傳輸方式:A要向B發送一個文件,于是發出一個文件傳送請求。服務器收到這個文件傳送請求后,轉發給B,同時或者在B應答后,將A的IP地址同時發送給B。B這個時候就得到了A的真實IP。這里的IP是你的本機IP。也就是說,如果A處在內網,B得到的地址就是一個內網地址。B得到了A的地址之后,就會嘗試去連接A。如果B也處于內網,那么,顯然A跟B之間的連接是無法建立的。這個時候,客戶端就會請求服務器進行文件中轉。因為服務器具有公網 IP,處在內網的A跟B都是可以連接到服務器的,于是,A跟B的文件傳送就通過服務器中轉的方式,順利進行。(注:服務器文件中轉使用443端口)
?
*? ?注:什么是內網、公網
? ??內網、公網是兩種Internet的接入方式。
? ??內網接入方式:上網的計算機得到的IP地址是Inetnet上的保留地址,保留地址有如下3種形式:
? ?10.x.x.x
? ?172.16.x.x至172.31.x.x
? ?192.168.x.x
? ? 內網的計算機以NAT(網絡地址轉換)協議,通過一個公共的網關訪問Internet。
? ??內網的計算機可向Internet上的其他計算機發送連接請求,但Internet上其他的計算機無法向內網的計算機發送連接請求。
? ??公網接入方式:上網的計算機得到的IP地址是Inetnet上的非保留地址。公網的計算機和Internet上的其他計算機可隨意互相訪問。
?
? ??所以,如果一個局域網只開放80端口,QQ是可以登陸成功的,也可以進行聊天。但傳送文件也是不可以的,除非你們都在同一個內網。如果局域網還同時開放443端口,那么,恭喜你,QQ的功能你都可以正常使用。
?
?
QQ是不是TCP和UDP一起用?如果用UDP,如何做到信息的可靠發送??
答Q即可以使用TCP也可以使用UDP,但QQ默認是使用UDP協議,因為UDP協議消耗資源小,發送速度快,但當UDP協議不能正常轉發的時候,就會采用TCP協議進行發送.?
而信息的可靠發送是通過各種驗證機制來完成的,這一點你可以去GOOGLE之類的網站去搜索下.?
?
QQ用的是UDP打洞技術還是HTTP遂道??
答:發送消息的時候是UDP打洞,登陸的時候使用HTTP~因為登陸服務器其實就是一個HTTP服務器,只不過不是常用的那些,那個服務器是TX自行開發的
?
因為用戶一般都是在局域網內,地址都為私有IP,IM服務器是如何將信息轉發到用戶的??
答:如果使用TCP就沒什么好說了~由內網向外網連接,只要能夠連接上進行握手了,消息就可以暢通無阻的進行發送了.如果使用UDP的話,就是使用的打洞技術了,只要通道打通了,發送消息基本和TCP沒什么區別,要做的只是維護消息的完整性而已.
?
?
QQ是一個基于TCP/UDP協議的通訊軟件,而MSN是基于TCP協議的通訊軟件。
?
那么QQ是如何通訊的呢?在TCP/IP協議中,唯一標識一個應用進程的是socket,它通過網絡層的IP地址和傳輸層的端口號來實現,對與同一個IP地址的內部網絡,通過不同的端口號來標識不同的QQ進程;當你登陸QQ游戲服務器的時候,服務器會保留你的保留IP地址和端口號信息,并在你的好友的QQ進程中進行列表顯示,然后兩個進程就可以通信了。?
通常,發送文件的計算機首先要通過消息服務器將其IP地址發送給接收計算機,當接收計算機同意接收的確認消息反饋到消息服務器后,消息服務器將據此設置好文件傳輸對話。隨即,發送計算機與接收計算機就會在確定好的端口范圍內,建立起TCP或UDP連接開始文件的檢索與傳輸。?
在默認狀態下,QQ優先采用了UDP(User Data Protocol,用戶數據報協議)協議傳送數據,而對可靠性要求高的數據通訊系統往往使用TCP協議傳輸數據。與TCP協議不同,UDP協議并不提供數據傳送的驗證機制——在整個文件傳輸過程中如果出現數據報的丟失,協議本身并不能作出任何的檢測或提示。因此,通常人們把UDP協議稱為不可靠的傳輸協議。?
UDP協議適用于無須應答、要求時效的軟件使用,這樣的設計正好與QQ追求的目標相符,所以QQ優先使用了此協議進行一切功能應用。但是,由于 UDP協議具有不可靠性,常會因種種原因導致消息或數據的發送失敗(很多時候會發現發送文件給對方接收時,對方根本收不到要求接收文件的消息。或是發送聊天消息時,對方根本沒有收到過消息)。顯然,UDP協議由于排除了信息可靠傳遞機制,將安全和排序等功能移交給上層應用來完成,極大降低了執行時間,使速度得到了保證。QQ在數據傳輸上更注重實際性能,為了獲得更好的使用效果,往往可以犧牲一定的可靠性。因此,使用QQ來傳輸數據,在很多時候就成了一個“不錯”的選擇。?
一般內網傳輸首選QQ,速度最快,QQ的文件傳輸是直接個人對個人,采用P2P的傳輸方式,具有不需中轉的優勢,而且服務器都在國內,傳輸性能要高于外國IM軟件。總結
- 上一篇: 基于B/S模式的推送
- 下一篇: Python Unicode与中文处理