即時(shí)通訊系列閱讀
1. XMPP 簡介
XMPP(Extensible Messaging and Presence Protocol)是一種基于標(biāo)準(zhǔn)通用標(biāo)記語言的子集XML 的協(xié)議,它繼承了在XML 環(huán)境中靈活的發(fā)展性。因此,基于XMPP 的應(yīng)用具有超強(qiáng)的可擴(kuò)展性。經(jīng)過擴(kuò)展以后的XMPP 可以通過發(fā)送擴(kuò)展的信息來處理用戶的需求,以及在XMPP 的頂端建立如內(nèi)容發(fā)布系統(tǒng)和基于地址的服務(wù)等應(yīng)用程序。
而且,XMPP 包含了針對服務(wù)器端的軟件協(xié)議,使之能與另一個(gè)進(jìn)行通話,這使得開發(fā)者更容易建立客戶應(yīng)用程序或給一個(gè)配好系統(tǒng)添加功能。
XMPP(可擴(kuò)展消息處理現(xiàn)場協(xié)議)是基于可擴(kuò)展標(biāo)記語言(XML)的協(xié)議,它用于即時(shí)消息(IM)以及在線現(xiàn)場探測。它在促進(jìn)服務(wù)器之間的準(zhǔn)即時(shí)操作。這個(gè)協(xié)議可能最終允許因特網(wǎng)用戶向因特網(wǎng)上的其他任何人發(fā)
送即時(shí)消息,即使其操作系統(tǒng)和瀏覽器不同。
XMPP 的前身是Jabber,一個(gè)開源形式組織產(chǎn)生的網(wǎng)絡(luò)即時(shí)通信協(xié)議。XMPP 目前被IETF 國際標(biāo)準(zhǔn)組織完成了標(biāo)準(zhǔn)化工作。標(biāo)準(zhǔn)化的核心結(jié)果分為兩部分;XMPP 其實(shí)就是用TCP 傳的是XML 文件流。
xmpp特點(diǎn)
- 開放:XMPP協(xié)議是自由、開放、公開的,并且易于了解。 而且在客戶端 、 服務(wù)器 、 組件 、 源碼庫等方面,都已經(jīng)各自有多種實(shí)現(xiàn)。
- 標(biāo)準(zhǔn):互聯(lián)網(wǎng)工程工作小組( IETF )已經(jīng)將Jabber的核心XML流協(xié)議以XMPP之名,正式列為認(rèn)可的實(shí)時(shí)通信及Presence技術(shù)。 而XMPP的技術(shù)規(guī)格已被定義在RFC?3920及RFC?3921 。 任何IM供應(yīng)商在遵循XMPP協(xié)議下,都可與Google Talk實(shí)現(xiàn)連接。
- 證實(shí)可用:第一個(gè)Jabber(現(xiàn)在XMPP)技術(shù)是Jeremie Miller在1998年開發(fā)的,現(xiàn)在已經(jīng)相??當(dāng)穩(wěn)定;數(shù)以百計(jì)的開發(fā)者為XMPP技術(shù)而努力。 今日的互聯(lián)網(wǎng)上有數(shù)以萬計(jì)的XMPP服務(wù)器運(yùn)作著,并有數(shù)以百萬計(jì)的人們使用XMPP實(shí)時(shí)傳訊軟件。
- 分散式:XMPP網(wǎng)絡(luò)的架構(gòu)和電子郵件十分相像;XMPP核心協(xié)議通信方式是先創(chuàng)建一個(gè)stream,XMPP以TCP傳遞XML數(shù)據(jù)流,沒有中央主服務(wù)器。 任何人都可以運(yùn)行自己的XMPP服務(wù)器,使個(gè)人及組織能夠掌控他們的實(shí)時(shí)傳訊體驗(yàn)。
- 安全:任何XMPP協(xié)議的服務(wù)器可以獨(dú)立于公眾XMPP網(wǎng)絡(luò)(例如在企業(yè)內(nèi)部網(wǎng)絡(luò)中),而使用SASL及TLS等技術(shù)的可靠安全性,已自帶于核心XMPP技術(shù)規(guī)格中。
- 可擴(kuò)展:XML 命名空間的威力可使任何人在核心協(xié)議的基礎(chǔ)上建造定制化的功能;為了維持通透性,常見的擴(kuò)展由XMPP標(biāo)準(zhǔn)基金會 。 彈性佳 XMPP除了可用在實(shí)時(shí)通信的應(yīng)用程序,還能用在網(wǎng)絡(luò)管理、內(nèi)容供稿、協(xié)同工具、文件共享、游戲、遠(yuǎn)程系統(tǒng)監(jiān)控等。
- 多樣性:用XMPP協(xié)議來建造及布署實(shí)時(shí)應(yīng)用程序及服務(wù)的公司及開放源代碼計(jì)劃分布在各種領(lǐng)域;用XMPP技術(shù)開發(fā)軟件,資源及支持的來源是多樣的,使得使你不會陷于被“綁架”的困境。
下面給大家介紹XMPP 通信中最核心的三個(gè)XML 節(jié)(stanza)。這些節(jié)(stanza)有自己的作用和目標(biāo),通過組織不同的節(jié)(stanza),就能達(dá)到我們各種各樣的通信目的。
<stream:stream>
<iq
id="roster1"
type='get'>
<query xmlns='jabber:iq:roster'/>
</iq>
<message
from='test_account@jabber.org'
to='william_duan@jabber.org'
type='chat'>
<body>Hello</body>
</message>
<presence type='unavailable'/>
</stream:stream>
在上面的xml 中,我們可以看到一些XMPP 節(jié)(stanza),包括<iq>,<message>以及<presence>。接下來就對這些節(jié)(stanza)做一個(gè)大致的了解。
1.1節(jié)的共通屬性
1.1.1 from
表示節(jié)(stanza)的發(fā)送方,在發(fā)送節(jié)(stanza)時(shí),一般來說不推薦設(shè)定,服務(wù)器會自動設(shè)定正確的值,如果設(shè)定了不正確的值,服務(wù)器將會拒收該節(jié)(stanza)信息。如果在客戶端到服務(wù)器端的通信中接收的節(jié)(stanza)中沒有該屬性,會被默認(rèn)解釋為信息是由服務(wù)器發(fā)出的。如果在服務(wù)器到服務(wù)器的通信中接收的節(jié)(stanza)中沒有本屬性,則會被解釋為一個(gè)error。
1.1.2 to
表示節(jié)(stanza)的接收方。如果在客戶端到服務(wù)器端的通信中沒有設(shè)置本屬性,服務(wù)器會默認(rèn)解釋為信息是發(fā)給自己的。
1.1.3 type
指定節(jié)(stanza)的類型.每種節(jié)(stanza)都會有幾種可能的設(shè)定值。所有的節(jié)(stanza)都會有一個(gè)error 類型,表明這個(gè)節(jié)(stanza)是一個(gè)error 回應(yīng),對這樣的節(jié)(stanza)信息不需要進(jìn)行回應(yīng)。
1.1.4 id
表示一個(gè)特定的請求。在<iq>節(jié)中,這個(gè)屬性是必須要指定的,但是在其他兩個(gè)節(jié)(stanza)中是一個(gè)可選屬性。
1.2 iq 節(jié)點(diǎn)
iq 節(jié)(stanza)主要是用于Info/Query 模式的消息請求,他和Http 協(xié)議比較相似。可以發(fā)出get 以及set 請求,就如同http 中的GET 以及POST。iq 節(jié)點(diǎn)需要有回應(yīng),有g(shù)et,set 兩種請求以及result,error 兩種回應(yīng)。發(fā)送查詢消息示例:
<iq from="william_duan@jabber.org/study" type="get" id="roster1">
<query xmlns="jabber:iq:roster"/>
</iq>
上面xml 的意思是william_duan 查詢自己的聯(lián)系人列表。
接收到回應(yīng)示例:如果請求錯(cuò)誤:
<iq to="william_duan@jabber.org/study" type="error" id="roster1">
<query xmlns="jabber:iq:roster"/>
<error type="cancel">
<feature-not-implemented xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
</error>
</iq>
如果請求成功:
<iq to="william_duan@jabber.org/study" type="result" id="roster1">
<query xmlns="jabber:iq:roster"/>
<item jid="account_one@jabber.org" name="one"/>
<item jid="account_two@jabber.org" name="two"/>
</iq>
william 獲取到了自己的花名冊列表,該列表中有兩個(gè)好友。
1.3 message 節(jié)點(diǎn)
正如名字一樣,message 節(jié)(stanza)用于用戶之間傳遞消息。這消息可以是單純的聊天信息,也可以某種格式化的信息。message 節(jié)點(diǎn)信息是傳遞之后就被忘記的。當(dāng)消息被送出之后,發(fā)送者是不管這個(gè)消息是否已經(jīng)送出或者什么時(shí)候被接收到。通過擴(kuò)展協(xié)議,可以改變這樣一種狀況。
私人會話示例:
<message from="william_duan@jabber.org" to="test_account@jabber.org" type="chat">
<body>Come on</body>
<thread>23sdfewtr234weasdf</thread>
</message>
群組會話示例:
<message from="test_account@jabber.org" to="william_duan@jabber.org" type="groupchat">
<body>welcome</body>
</message>
1.4 presence 節(jié)點(diǎn)
presence 節(jié)(stanza)用來控制和表示實(shí)體的在線狀態(tài),可以展示從離線到在線甚至于離開,不能打擾等復(fù)雜狀態(tài),另外,還能被用來建立和結(jié)束在線狀態(tài)的訂閱。
在線狀態(tài)示例:
//設(shè)定用戶狀態(tài)為在線
<presence/>
..............................
//設(shè)定用戶狀態(tài)為離線
<presence type="unavailable"/>
..............................
//用于顯示用戶狀態(tài)的詳細(xì)信息。上面的例子表明用戶因?yàn)閍t the ball 在離開狀態(tài)。
<presence>
<show>away</show>
<status>at the ball</status>
</presence>
<show>標(biāo)簽在presence 節(jié)點(diǎn)中最多出現(xiàn)一次,可以有以下取值:away,chat,dnd,xa。
- away:離線
- chat:交談中
- dnd:希望不被打擾
- xa:離開一段時(shí)間
<status>標(biāo)簽用于顯示額外信息。
在線狀態(tài)預(yù)定(presence subscription) :
<presence
from="william_duan@jabber.org"
to="test_account@jabber.org"
type="subscribe"/>
..............................
<presence
from="test_account@jabber.org"
to="william_duan@jabber.org"
type="subscribed"/>
通過上述交互,william_duan 就能看到test_account 的在線狀態(tài),并能接收到test_account 的在線狀態(tài)通知了。
2. XMPP 服務(wù)器平臺
我們在學(xué)習(xí)JavaWEB 的時(shí)候要用到web 服務(wù)器,那么我們就選擇了Tomcat 作為web 服務(wù)器。同樣的道理我們要學(xué)習(xí)即時(shí)通信,這整個(gè)體系是一個(gè)C/S 架構(gòu),Server 端不需要我們編寫,那么我們就選擇一款市場上免費(fèi)開源的服務(wù),除了Openfire 暫無他選,Openfire 是開源免費(fèi)功能強(qiáng)大的IM 服務(wù)器。為什么選擇Openfire 呢?請往下看。
Openfire 采用Java 開發(fā),開源的實(shí)時(shí)協(xié)作(RTC)服務(wù)器基于XMPP(Jabber)協(xié)議。Openfire 安裝和使用都非常簡單,并利用Web 進(jìn)行管理。單臺服務(wù)器可支持上萬并發(fā)用戶。您可以使用它輕易的構(gòu)建高效率的即時(shí)通信服務(wù)器。由于是采用開放的XMPP 協(xié)議,您可以使用各種支持XMPP 協(xié)議的IM 客戶端軟件登陸服務(wù)。
2.1 案例-Openfire 的下載和安裝
下載地址:http://www.igniterealtime.org/downloads/index.jsp
我們下載windows 平臺的openfire_3_10_2.exe 文件。
雙擊開始安裝。
選擇中文(簡體),然后點(diǎn)擊確定。
選擇我接受協(xié)議,然后點(diǎn)擊下一步。
選擇好安裝路徑,然后點(diǎn)擊下一步。
耐心等待,大概50 秒。
點(diǎn)擊完成。
啟動之后彈出如上界面,有異常!大概應(yīng)該是日志相關(guān)的文件找不到。我們先不管,點(diǎn)擊Launch Admin 啟動
管理控制臺。
我們注意上圖中的地址欄,端口是9090,這是openfire 使用的端口,我們有時(shí)候喜歡把tomact 配置層9090,一定注意不要占用了該端口。
我們選擇中文(簡體),然后點(diǎn)擊continue。
設(shè)置域,其他設(shè)置默認(rèn)即可。然后點(diǎn)擊繼續(xù)(上一頁還是continue,選中過中文后可就成繼續(xù)了)。
注意:這個(gè)時(shí)候必須先確保本機(jī)已經(jīng)安裝了MySQL,并創(chuàng)建了數(shù)據(jù)庫,我創(chuàng)建的數(shù)據(jù)庫名字就叫做openfire。
然后在該數(shù)據(jù)庫中執(zhí)行sql 腳本,該sql 腳本是openfire 提供的,位置位于:
在數(shù)據(jù)庫中將該腳本內(nèi)容執(zhí)行一下,讓其初始化數(shù)據(jù)表結(jié)構(gòu)。
然后點(diǎn)擊繼續(xù),進(jìn)入下一個(gè)頁面。
使用默認(rèn)配置,繼續(xù)點(diǎn)擊繼續(xù)。進(jìn)入下一個(gè)頁面。
在上面填寫郵箱和管理員密碼,然后點(diǎn)擊繼續(xù)。
成功啦!點(diǎn)擊登錄到控制臺,進(jìn)入如下界面。
openfire 管理員默認(rèn)賬號為admin,密碼就是我們上一個(gè)界面設(shè)置的密碼。輸入賬號和密碼,然后點(diǎn)擊登錄。
進(jìn)入下一個(gè)界面。
我們就來瀏覽一下成功后的界面吧
用戶列表界面:
會話界面:
分組聊天界面:
3. XMPP 客戶端平臺
3.1 Spark 客戶端的下載和安裝
Spark 是一個(gè)開源,跨平臺IM 客戶端。它的特性支持集組聊天,電話集成和強(qiáng)大安全性能。如果企業(yè)內(nèi)部部署IM 使用Openfire+Spark 是最佳的組合。其官網(wǎng)對Spark 的介紹如下:
Spark is an Open Source, cross-platform IM client optimized for businesses and organizations. It features built-in support for group chat, telephony integration, and strong security. It also offers a great end-user experience with features like in-line spell checking, group chat room bookmarks, and tabbed conversations。
Combined with the Openfire server, Spark is the easiest and best alternative to using un-secure public IM networks。
下載好以后:
雙擊安裝。安裝非常簡單,一路點(diǎn)擊下一步即可。
點(diǎn)擊Next,進(jìn)入下一個(gè)界面:
點(diǎn)擊Next......Next 進(jìn)入下一個(gè)界面:
看到如下界面就OK 了,如果在上一個(gè)界面點(diǎn)擊Finish 沒有起效,那么可以找到生成的桌面快捷圖標(biāo),雙擊。
點(diǎn)擊賬號,進(jìn)入下一個(gè)界面。
在上圖中輸入用戶、密碼和服務(wù)器地址。
然后創(chuàng)建賬號。
在上圖中點(diǎn)擊確定,進(jìn)入如下圖界面。
點(diǎn)擊Login 進(jìn)入如下界面:
在openfire 中刷新界面,打開用戶/組選項(xiàng)卡,可以看到所有注冊的用戶列表。
3.2 Spark 和Openfire 通信原理
從網(wǎng)上找到一個(gè)Spark 和Openfire 直接通訊架構(gòu)圖。看懂這張圖就知道他們之間是如何通信的了。
Smack 是對XMPP 協(xié)議的封裝庫,Smack 是XMPP 協(xié)議的Java 層的封裝。讓我們Java 程序員不用直接跟枯燥無味的XML 打交道(生成XML 和解析XML)。
隨著移動互聯(lián)網(wǎng)的快速發(fā)展,尤其是即時(shí)通信的發(fā)展,幾乎90%以上的App 都有這樣的功能。因此asmack也與13 年誕生,asmack 其實(shí)就是Android Smack 的簡稱。asmack 也是我們該門課程用到的主要API。
下面請看第5 章吧,讓我們一起學(xué)習(xí)如何使用asmack 打造我們的交友神器。