基于XMPP協(xié)議的Android即時(shí)通信系統(tǒng)
當(dāng)前位置:點(diǎn)晴教程→知識(shí)管理交流
→『 技術(shù)文檔交流 』
設(shè)計(jì)基于開源的XMPP即時(shí)通信協(xié)議,采用C/S體系結(jié)構(gòu),通過GPRS無(wú)線網(wǎng)絡(luò)用TCP協(xié)議連接到服務(wù)器,以架設(shè)開源的Openfire服務(wù)器作為即時(shí)通訊平臺(tái)。 系統(tǒng)主要由以下部分組成:一是服務(wù)器,負(fù)責(zé)管理發(fā)出的連接或者與其他實(shí)體的會(huì)話,接收或轉(zhuǎn)發(fā)XML(ExtensibleMarkup Language)流元素給授權(quán)的客戶端、服務(wù)器等;二是客戶終端。它與服務(wù)器相連,通過XMPP獲得由服務(wù)器或任何其它相關(guān)的服務(wù)所提供的全部功能。三是協(xié)議網(wǎng)關(guān)。完成XMPP協(xié)議傳輸?shù)男畔⑴c外部消息系統(tǒng)可識(shí)別信息間的翻譯。再就是XMPP網(wǎng)絡(luò)。實(shí)現(xiàn)各個(gè)服務(wù)器、客戶端間的連接。系統(tǒng)采用客戶端(Client)/服務(wù)端(Server)架構(gòu)體系結(jié)構(gòu)。 客戶端: 客戶端基于Android平臺(tái)進(jìn)行開發(fā)。負(fù)責(zé)初始化通信過程,進(jìn)行即時(shí)通信時(shí),由客戶端負(fù)責(zé)向服務(wù)器發(fā)起創(chuàng)建連接請(qǐng)求。系統(tǒng)通過GPRS無(wú)線網(wǎng)絡(luò)與Internet網(wǎng)絡(luò)建立連接,通過服務(wù)器實(shí)現(xiàn)與Android客戶端的即時(shí)通信腳。 服務(wù)器端: 服務(wù)器端則采用Openfire作為服務(wù)器。允許多個(gè)客戶端同時(shí)登錄并且并發(fā)的連接到一個(gè)服務(wù)器上。服務(wù)器對(duì)每個(gè)客戶端的連接進(jìn)行認(rèn)證,對(duì)認(rèn)證通過的客戶端創(chuàng)建會(huì)話,客戶端與服務(wù)器端之間的通信就在該會(huì)話的上下文中進(jìn)行。 1.1服務(wù)器端設(shè)計(jì)(這塊幾乎可以說是有成品了。不用多糾結(jié)) androidpn服務(wù)器端是java語(yǔ)言實(shí)現(xiàn)的,基于openfire開源工程,Web部分采用的是spring框架,這一點(diǎn)與openfire是不同的。Androidpn服務(wù)器包含兩個(gè)部分,一個(gè)是監(jiān)聽特定端口上的XMPP服務(wù),負(fù)責(zé)與客戶端的XMPPConnection類進(jìn)行通信,作用是用戶注冊(cè)和身份認(rèn)證,并發(fā)送推送通知消息。另外一部分是Web服務(wù)器,采用一個(gè)輕量級(jí)的HTTP服務(wù)器,負(fù)責(zé)接收用戶的Web請(qǐng)求。 主要的四個(gè)組成部分,分別是SessionManager,Auth Manager,PresenceManager以及Notification Manager。SessionManager負(fù)責(zé)管理客戶端與服務(wù)器之間的會(huì)話,Auth Manager負(fù)責(zé)客戶端用戶認(rèn)證管理,Presence Manager負(fù)責(zé)管理客戶端用戶的登錄狀態(tài),NotificationManager負(fù)責(zé)實(shí)現(xiàn)服務(wù)器向客戶端推送消息功能。 系統(tǒng)客戶端基于Android手機(jī)平臺(tái)。采用XMPP作為即時(shí)通訊協(xié)議。XMPP是基于XML,實(shí)現(xiàn)任意兩個(gè)網(wǎng)絡(luò)終端準(zhǔn)實(shí)時(shí)的交換結(jié)構(gòu)化信息的通信協(xié)議。采用Android平臺(tái)提供的XML解析包對(duì)XML進(jìn)行解析。由于應(yīng)用活動(dòng)都運(yùn)行于主線程。故用多線程技術(shù)來解決系統(tǒng)通訊問題。針對(duì)通信安全問題.系統(tǒng)的用戶信息和聊天信息在客戶端存儲(chǔ)在Android平臺(tái)自身所帶的SQLite數(shù)據(jù)庫(kù)中,多媒體文件和圖片文件存儲(chǔ)在Android平臺(tái)虛擬文件存儲(chǔ)設(shè)備SD Card中。 通訊模塊負(fù)責(zé)與服務(wù)器建立通訊舊。通過創(chuàng)建3個(gè)線程來進(jìn)行處理。分別負(fù)責(zé)消息的發(fā)送、接收和心跳信息的發(fā)送;解析模塊主要用來解析XML數(shù)據(jù)流。根據(jù)解析元素不同類型封裝成不同的數(shù)據(jù)對(duì)象:數(shù)據(jù)模塊定義整個(gè)客戶端中大部分的數(shù)據(jù)類型和對(duì)象;應(yīng)用模塊包括即時(shí)通信、圖片瀏覽和音樂播放。是客戶端和用戶交流的接口;加密模塊對(duì)發(fā)送和接收的消息進(jìn)行加解密。以確保通訊數(shù)據(jù)的安全。 系統(tǒng)的客戶端分為5大模塊進(jìn)行設(shè)計(jì)開發(fā),如圖2所示。通訊模塊負(fù)責(zé)與服務(wù)器建立通訊舊。通過創(chuàng)建3個(gè)線程來進(jìn)行處理。分別負(fù)責(zé)消息的發(fā)送、接收和心跳信息的發(fā)送;解析模塊主要用來解析XML數(shù)據(jù)流。根據(jù)解析元素不同類型封裝成不同的數(shù)據(jù)對(duì)象:數(shù)據(jù)模塊定義整個(gè)客戶端中大部分的數(shù)據(jù)類型和對(duì)象;應(yīng)用模塊包括即時(shí)通信、圖片瀏覽和音樂播放。是客戶端和用戶交流的接口;加密模塊對(duì)發(fā)送和接收的消息進(jìn)行加解密。以確保通訊數(shù)據(jù)的安全。 加密(首先將二進(jìn)制碼轉(zhuǎn)換成BASE64碼,在轉(zhuǎn)換成BASE64碼之后,再進(jìn)行MD5加密,) XMPP服務(wù)器之間、客戶與服務(wù)器之間采用的是TCP連接。TCP提供一種雙向連接、可靠的字節(jié)流服務(wù)。保持一個(gè)實(shí)時(shí)雙向的傳輸通道。TCP將用戶數(shù)據(jù)打包構(gòu)成報(bào)文段。它發(fā)送數(shù)據(jù)后啟動(dòng)一個(gè)定時(shí)器,等待對(duì)端數(shù)據(jù)確認(rèn),另一端對(duì)收到的數(shù)據(jù)進(jìn)行確認(rèn),對(duì)失序的數(shù)據(jù)重新排序,并丟棄重復(fù)數(shù)據(jù);TCP提供端到端的流量控制。計(jì)算和驗(yàn)證一個(gè)強(qiáng)制性的端到端檢驗(yàn)。但是GPRS網(wǎng)絡(luò)對(duì)TCP鏈路存在一個(gè)限制。當(dāng)TCP鏈路在長(zhǎng)時(shí)間無(wú)有數(shù)據(jù)流量時(shí)。會(huì)自動(dòng)降低此鏈路的優(yōu)先級(jí)直至強(qiáng)制斷開此鏈路。所以在應(yīng)用中.采用發(fā)送心跳的方式來維持此鏈路。數(shù)據(jù)格式 XML是XMPP系統(tǒng)架構(gòu)的核心。它能表述幾乎任何一種結(jié)構(gòu)化數(shù)據(jù)。特別是XMPP利用XML數(shù)據(jù)流進(jìn)行客戶端一服務(wù)器端、服務(wù)器端一服務(wù)器端的通信。XML數(shù)據(jù)流一般是由客戶端發(fā)起至服務(wù)端,XML數(shù)據(jù)流的有效時(shí)間直接與用戶的在線會(huì)話有效時(shí)間相關(guān)聯(lián)。 協(xié)議消息格式XMPP協(xié)議包括3個(gè)頂層XML元素:Message、Presence和IQm。Message用來表示傳輸?shù)南?,?dāng)用戶發(fā)送一條消息時(shí)。就會(huì)在流的上下文中插入一個(gè)Message元素,中間有用戶發(fā)送的相關(guān)信息;Presence用來表示用戶的狀態(tài)。當(dāng)用戶改變自己的狀態(tài)時(shí)。就會(huì)在數(shù)據(jù)流的上下文中插入一個(gè)Presence元素,用來表示用戶現(xiàn)在的狀態(tài);IQ用來表示一種請(qǐng)求,響應(yīng)機(jī)制,從一個(gè)實(shí)體發(fā)送請(qǐng)求,另外一個(gè)實(shí)體接受請(qǐng)求并響應(yīng)。 后臺(tái)Servic: 從類的層次看這個(gè)結(jié)構(gòu)比較簡(jiǎn)單,讓其變得復(fù)雜的是,其里面有三個(gè)線程:主線程,進(jìn)行Xmpp通信線程,連接出錯(cuò)重試線程。 對(duì)圖說明: 1. 在NotificationService里創(chuàng)建一個(gè)單線程,讓其對(duì)服務(wù)器進(jìn)行連接,由于使用Xmpp連接服務(wù)器要分為三步:連接,注冊(cè),登陸。所以用一個(gè)棧來保存要執(zhí)行的Task任務(wù)(ConnectTask,RegisterTask,LoginTask),還后再按這個(gè)順序進(jìn)行執(zhí)行。 2. 連接Xmpp服務(wù)器的線程用的是Executors.newSingleThreadExecutor(),這個(gè)本身可以不停的submit任務(wù)。為什么還要自己用一個(gè)棧來保存Task了 3. 連接線程在連接,注冊(cè),登陸的過程中,都有可能出錯(cuò),都可能會(huì)失敗,這時(shí)我就要有一個(gè)重連的機(jī)制,在Androidpn里開了另外一個(gè)線程來進(jìn)行重試,其重試不是每次都按多少秒來進(jìn)行重試,而是有其自己的規(guī)則。 4. 在LoginTask里,如果登陸了服務(wù)器端,其就會(huì)注冊(cè)一個(gè)監(jiān)聽器,用于監(jiān)聽服務(wù)器push的數(shù)據(jù)包(Packet),再通過發(fā)送廣播的方式來通知要進(jìn)行顯示的程序。 5. 在登陸服務(wù)器后,也有可能出錯(cuò),所以在登陸后,會(huì)設(shè)置一個(gè)ConnectionListener,用于監(jiān)聽連接出錯(cuò)的時(shí)候,再合適重連線程,進(jìn)行重連 6. 在登陸過程中,有一種錯(cuò)誤要單獨(dú)處理,就是賬號(hào)和密碼無(wú)效的時(shí)候,這個(gè)時(shí)候其返回的狀態(tài)碼是401,這種情況應(yīng)該把本地保存的帳號(hào)和密碼都清掉,再重新進(jìn)行連接,不然會(huì)永遠(yuǎn)都登陸不上服務(wù)器端。 由于該系統(tǒng)所有的功能實(shí)現(xiàn)都是基于網(wǎng)絡(luò)間的XML流的通信,所以,需要有一個(gè)模塊專門負(fù)責(zé)網(wǎng)絡(luò)問通信和XML流的處理,主要功能包括服務(wù)器和客戶端之問通信時(shí)TCP套接字的處理,XML流的解析、存儲(chǔ)等功能。數(shù)據(jù)模塊負(fù)責(zé)XML流的解析和封裝的XML模塊,主要功能是:將XML流解析成java對(duì)象,將iava對(duì)象封裝成XML流; 其流程是XMPP服務(wù)器接收到XML流之后,會(huì)有瀆取器將其讀取出來并將其作為入口參數(shù)傳入XML解析器,XML解析器通過對(duì)其命名空間的解析,從而確定將剩余的XML元素解析出來并傳入相應(yīng)的;ava對(duì)象中,從而最終將XML轉(zhuǎn)換成iava對(duì)象,然后將iava對(duì)象傳入應(yīng)用程序模塊中,實(shí)現(xiàn)其請(qǐng)求完成的功能并返回iava對(duì)象,但是該iava對(duì)象不能在網(wǎng)絡(luò)中直接傳輸,必須先轉(zhuǎn)換成XML節(jié),于是,該iava對(duì)象會(huì)被傳入XML封裝器中,被封裝成XML節(jié),通過XMPP服務(wù)器的發(fā)送端口發(fā)往目的節(jié)點(diǎn)。 java對(duì)象處理模塊處理流程如下:當(dāng)該模塊接收到iava對(duì)象時(shí),會(huì)先將該對(duì)象通過解密算法和解密密鑰解密成base64碼,然后f耳將base64碼轉(zhuǎn)換成二進(jìn)制碼,從而實(shí)現(xiàn)對(duì)java對(duì)象的解析。當(dāng)完成業(yè)務(wù)邏輯處理后,該模塊會(huì)將返回的java對(duì)象先由二進(jìn)制碼轉(zhuǎn)換成base64碼,然后用加密算法將其加密,這里的加密算法是由雙方在建立會(huì)話時(shí)通過三次握手協(xié)議協(xié)商的。 當(dāng)XML節(jié)被封裝成java對(duì)象后,必須被轉(zhuǎn)發(fā)至訂:確的模塊中加以處理,這就要求有一個(gè)路由轉(zhuǎn)發(fā)模塊,如圖3—3所示。該模塊的實(shí)現(xiàn)原理是:在系統(tǒng)啟動(dòng)時(shí)加載該路由模塊,從而在內(nèi)存中創(chuàng)建了一塊路由模塊,記錄了命名空和功能模塊之間的對(duì)應(yīng)關(guān)系,當(dāng)iava對(duì)象被封裝好之后,系統(tǒng)會(huì)讀出其命名空間,再在路由表中查找其所對(duì)應(yīng)的模塊,從而動(dòng)態(tài)地加載該模塊,并將該java對(duì)象轉(zhuǎn)發(fā)至該模塊,從而實(shí)現(xiàn)路山轉(zhuǎn)發(fā)的功能。 該文章在 2013/2/25 17:37:47 編輯過 |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |