一、XMPP是可擴展消息與存在協議,主要用於im。
二、他是一種相似於http協議的傳輸數據協議。過程如:「解包裝—>包裝」過程。node
三、在XMPP中,有三個角色:client,server。網關。 在三者之間可以進行隨意兩兩通訊。ios
server承擔client信息記錄。鏈接管理和信息的路由功能。網關承擔與異構即時通訊系統的互聯互通。安全
四、XMPP的基本網絡形式是單client經過TCP/IP鏈接到單server,而後傳輸XML。
五、他是基於C/S結構的,分佈式網絡。使用xml的數據格式。
六、XMPP的核心部分是由他的節構成的。
七、xmpp網絡:server,client,組件,插件。服務器
八、xmpp的jid與電子郵件地址相似。節點、域、資源。
九、xmpp主詞彙表有3種節:<message>(用於在實體間交換「發後不管」消息)<presence>(傳達出席狀態變化並用來操縱出息訂閱)<iq>(提供相似http的get和post操做的請求響應語義。).
十、xmpp會話:鏈接、流的創建、身份驗證、會話正文、斷開鏈接。網絡
從一個client到還有一個client的jabber消息和數據都要經過xmpp server。session
1.client鏈接到server。
2.server 利用本地文件夾系統的證書對其認證。
3.client制定目標地址。讓server告知目標狀態。
4.server查找,連接並進行相互認證。
5.client間進行交互。app
核心節:<message><presene><iq>
一、<stream> xmpp以其標記開始。
二、<presence>用來代表用戶狀態。負載均衡
可以來廣播或「公佈-訂閱」。<status>網絡狀態、<show>可用狀態、<priority>資源優先級。
三、<iq>一種請求/響應機制。分佈式
四、<message>用於兩個jabber用戶發送消息。ide
<body>是消息內容。他包括<subject/>(消息標題)<body/>(消息內容)<thread/>(跟蹤會話線索)子標籤。
簡單會話:
<stream:stream> 建立一個xmpp流
<iq type=’get’> 請求elizabeth的花名冊,也就是她的所有已存儲的聯繫人列表。
<query xmlns=’jabber:iq:roster’/>
</iq>
<presence/> 通知server她已經在線並可以訪問。 當他注意到darcy在線的時候。就會發個message節。
<message to=’darcy@pemberley.lib’
from=’ellizabaeth@longbourn.lit/ballroom’
type=’chat’>
<body>sdf</body>
</message>
<presence type=’unavailable’/> 告訴server,這是不可訪問的要關閉
</stream:stream>
支持通用屬性:from。to,type。id。
1)、from
識別此節的起始jid。這裏不建議在輸出的節上手工設置from屬性,server會在這些節經過時加入正確的from屬性,而假設錯誤地設置from屬性會致使server拒絕整個節。
client-server中。接收到的節上沒有from屬性,意味着該節來源於server自身,而在server-server中,缺乏from被視爲是錯誤。
2)、to
把xml節發送到to屬性指定的jid。他和from類似。
client-server流中沒有to屬性。那麼server將若是它是有意發給server自身的消息,建議在向server自身發消息時忽略to。
假設to屬性中指定的jid是一個用戶,那麼server有可能表明用戶來處理該節。
假設目的地是一個裸jid。那麼server將處理這個節。
假設目的地是一個完整的jid。那麼server將直接把該節路由到該用戶。
3)、type
這個屬性指定了三個節的詳細類型。
三個節都可以把type設置爲error,表示這個節是對已接收到的同一類型的節的錯誤影響,不要響應類型爲error的節。避免在網絡上出線反饋環節。
4)、id
給節指定id來輔助識別響應。對於iq節,id是必須的,但是對於其它的節id是可選的。假設某個節是爲了響應一個攜帶id屬性的節而產生的。那麼這個應答必須包括攜帶一樣值得id值。
id必須具備惟一性。這樣節的發送者就可以使用它來甄別響應了。
最簡單的作法就是讓id屬性值在給定的流中保持惟一性,以避免歧義。
在message和presence節的應答節通常僅限於報告錯誤,iq的應答節可以用來通知成功操做、確認命令或返回請求的數據。無論怎樣client都可以使用應答節的id屬性來識別與該節相關聯的請求節。
在短期內發送大量同類型的節,此時這個功能就很關鍵了。
因爲這些節的應答可能會以亂序形式到達。
1)、presence
他控制並報告實體的可訪問性。
(包含:在線,離線。 離開,請勿打攪等。 ) 他還可以用來創建和終止向其它實體公佈出席訂閱。
有了出席訂閱通知。咱們在即時通訊系統中就可以在發送消息以前知道接收者是否在線。
(1)、普通的presence
此時他是不包括type屬性的,假設有的話他的屬性值爲unavailable活着error。 在這裏,type屬性是沒有available值得。因爲咱們可以經過缺省的type來設定。
用戶可以經過發送不攜帶to屬性,並直接發往server的presence節來操縱出席狀態。例如如下:
<presence/> 前兩個節將用戶的出息狀態設置爲在線和離線
<presence type=‘unavailable’/> 離線
<presence>
<show>away</show> 僅僅能用在presence中,值away離開。chat聊天。end不但願被打攪。xa長期離開。 傳達用戶可訪問性的性質,它請求接收者的client使用這個消息來更新發送者出息狀態的可視化指示器。
<status>sf</status> 一我的們可讀的字符串。用戶能夠將其設置爲能夠傳達出席信息的不論什麼值。
聊天時,接收者的client中這個字符串通常緊挨着聯繫人名字顯示。
</presence>
<presence>
<status>sfdf</status>
<priority>22</priority> 優先級 同一時候具備多個回話的用戶可以使用優先級來指出哪個資源應該接收到那些發往該用戶裸jid的聊天消息。
</presence>
<presence>
<prioriry>11</pritority>
</presence>
(2)、擴展presence
比方將你正在聽歌,心情等信息廣播給其它聯繫人。這裏用流量較大。
(3)、出席訂閱
server會本身主動將出席信息廣播給聯繫人。用戶也會從所有他已經進行出席訂閱的聯繫人那裏接收到出席的狀態更新。
對於好友狀態的訂閱:A訂閱了B得出席信息。這裏並不是說B也訂閱了A得出席信息。
訂閱狀態:subscribe(創建訂閱),unsubscribe(取消訂閱),subscribed(應答創建),unsubscribed(應答取消)。
AB訂閱:
<presence from=‘a@longbourn.lit/outside’ to=‘b@pemberley.lit’ type=‘subscribe’/>
<presence from=‘b@pemberley.lit/library’ to=‘a@longbourn.lit/outside’ type=‘subscribed’/>
<presence from=‘b@pemberley.lit/library’ to=‘a@longbourn.lit’ type=‘subscribe’/>
<presence from=‘a@longbourn.lit/outside’ to=‘b@pemberley.lit/library’ type=‘subscribed’/>
(4)、定向出席
他是一種直接發給還有一個用戶或其它某個實體的普通presence節。這裏可以用來向那些沒有進行出席訂閱的實體傳送出席狀態信息。也就是暫時出席。
這裏當發送者變成不可訪問的狀態的時候。出席信息的接收者將會本身主動獲得通知,即便發送者忘記顯示的通知接收者。這裏可以使用定向出席來暫時地掌握某個用戶的可訪問性。
2)、message
從一端到還有一端發送消息。這個節屬於發出後再也不過問。可靠性不能保證。一旦消息發出去了。發送者就不會知道他是否是傳送出去了。也不會知道到達的時間。
message演示樣例:
單人聊天
<message from=‘a@netherfield.lit/frawing_room’ to=‘b@pemberley.lit’ type=‘chat’>
<body>adf</body>
</message>
多人聊天
benlent夫人向聊天室bennets@chat.merython.lit發送消息,bennet接收消息
<message from=’bennets@chat.merython.lit/mrs.bennet’ to=‘mr.bennet@longbourn.lit/study’ type=‘groupchat’>
<body>df</body>
</message>
(1)、消息類型
type指出:chat(一對一聊天),error。normal。group chat(多人聊天),headline(不支持或者不方便應答的本身主動化服務使用)。
type是可以省略的,默以爲normal。但是咱們應該提供一個type值,
(2)、消息內容
<body>元素包括着該消息中人們的可讀的內容。僅僅要有不一樣的xml:lang屬性就可以使用多個<body>。
<thread>元素用來建立線索,他的內容是一個用來區分不一樣線索的惟一標識符。應答節應該包括與所應答的節一樣的<thread>元素。 (線索:向電子郵件同樣)
在消息中,可以使用XHTML-IM來給消息提供格式化,超連接,以及富媒體。也可以使用Chat State Notifications來贊成用戶通告對方本身正在撰寫消息或有空。(qq的正在輸入)
3)、iq
這個節表示的時info/query(信息與查詢),他給xmpp童心提供請求和響應機制。
和http的基本工做原理想死,贊成獲取和設置查詢。(get 和 post)
每個節都需要有一個響應。但是這個節的必須的id將用來把響應與致使該響應的請求關聯起來。
type:get。set請求節; result,error爲響應節。
如下看演示樣例,每個iq節必須匹配id屬性
a向server發送了一個格式錯誤的花名冊請求
<iq from=a@longbourn.lit/garden’ type=‘get’ id=‘roster1’>
<query cmlns=‘jabber:iq:roster’/>
</iq>
<iq to=‘a@longbourn.lit/garden’ 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 from=a@longbourn.lit/garden’ type=‘get’ id=‘roster2’>
<query cmlns=‘jabber:iq:roster’/>
</iq>
<iq to=‘a@longbourn.lit/garden’ type=‘result’ id=‘roster2’>
<query xmlns=‘jabber:iq:roster’>
<item jid=‘b@longbourn.lit’ name=‘b’/>
<item jid=‘c@netherfield.lit’ name=‘c’/>
</query>
</iq>
a將b加入到花名冊,回覆空白iq來應答成功。
<iq from=‘a@longbourn.lit/garden’ type=‘set’ id=‘roster3’>
<query xmlns=‘jabber:iq:roster’>
<item jid=「b@pemberley.lit’ name=‘b’/>
</query>
</iq>
<iq to=‘a@longbourn.lit/garden’ type=‘result’ id=‘roster3’/>
4)、error
在錯誤提示節中,必須將type設置爲error,並且需要攜帶一個<error>子元素。
在error中。他的type類型爲:cancel(不該該重試),continue(警告信息),modify(發送的數據需要一些改動才幹夠被接受),auth(通知實體在以某種方式進行身份驗證以後重試),wait(報告server暫時遇到問題,稍後重發)。
在<error>中,必須包括一個錯誤條件做爲他的子元素,也可以在<error>元素的子元素中指定應用程序的特定錯誤條件。還可以包括一個<text>元素來進一步指出有關該錯誤的具體信息。
要注意的是每個錯誤條件元素都必須位於urn:ietf:params:xml:ns:xmpp-stanzas命名空間裏。
<error type=‘cancel’>
<not-allowed xmlns=‘urn:ietf:params:xml:ns:xmpp-stanzas’/> 這裏指出了通常性故障
<closed-node xmlns=‘http:/jabber.org/protocol/pubsub#errors’/> 給出了請缺德應用程序錯誤提示信息
<text xmlns=‘urn:ietf:params:xml:ns:xmpp-stanzas>dfs</text> 包括了問題描寫敘述
</error>
xmpp網絡有一個或多個地址jid。 a@aaa.llit 組成:節點、域、資源(帶有資源的jid是完整jid,沒有資源的jid是裸jid)。當中節點和資源是可選的,域是必選的。
當中域是server等的可解析dns名稱。僅僅有域組成的jid是有效的地址,表示server的地址。
當中指向域的節將由server自身處理。並且可能被路由到其它的組件或者插件上。
在本地時咱們通常會識別域中的一個特定的用戶,它位於@以前。本地部分還可以用來識別其它對象,多人聊天服務將每個聊天室顯示爲一個jid,節點部分指向聊天室。
jid的資源部分會標識一個特定的clientxmpp連接,對於xmppclient來講。每個連接均被指派一個資源,如 用 a@aaa.lit/study和a@aaa.lit/library 來尋址,當中資源部分也可以用來識別其它對象。在多人聊天時,jid的資源被用來識別聊天室中的一個特定的用戶。
client處理裸jid的時候。server本身將處理髮往client裸jid的節。
如:一條發往某個client的裸jid的消息將被轉發到該用戶的一個或多個已鏈接資源。假設該用戶離線,那麼就將該消息存儲之後傳送。但是發給完整jid的節通常會直接路由到該資源所在的client鏈接。可以將裸jid視爲尋址用戶的帳戶,而不是尋址該用戶的某個已鏈接的client。
鏈接,流的創建,身份驗證以及斷開鏈接。
1).鏈接
發送節前要創建xmpp流,在流存在以前要創建通往xmppserver的鏈接。
client和server利用域名系統將server的域名解析成一個能夠鏈接的地址。電子郵件服務特別的使用郵件交換臺記錄來提供處理特定域郵件的server列表。
這樣一個知名server地址就不用處理每一項服務請求了。
電子郵件在dns中有特殊的對待。現在服務記錄srv可用來爲隨意服務提供相似的功能。
當xmppclient或server鏈接到還有一個xmppserver的時候,首先要在server域中查詢適當的srv記錄。查詢應答中可能包括多條srv記錄,這樣就可以在多臺server間創建負載均衡連接。
當沒有找到合適的srv記錄的時候。應用程序試着直接鏈接到給定域。大多數庫也可以顯式制定要鏈接的server。
2).流的創建
向server發送起始元素<stream:stream>,就可以打開xmpp流。
server經過發送響應流的起始標記<stream:stream>進行響應。
server先發送<stream:features>元素,具體列舉xmpp流中支持的所有功能。
這些功能大多數與可用的加密和身份驗證選項有關。
client發給server
<?
xml version=’1.0′?>
<stream:stream xmlns=’jabber:client’
xmlns:straem=’http://ethrx.jabber.org/streams’
version=’1.0′
to=’pemberley.lit’>
server應答
<?xml version=’1.0′?
>
<stream:stream xmlns=’jabber:client’
xmlns:stream=’http://etherx.jabber.org/streams’
version=’1.0′
from=’pemberley.lit’
id=’dddd’
xml:lang=’en’>
<stream:features>
<stream:freatures>
<starttls xmlns=’urn:ietf:params:xml:ns:xmpp-tls’/>
<compression xmlns=’http://jabber.org/features/compress’>
<method>zlib</method>
</compression>
<mechanisms xmlns=’urn:ietf:params:xml:ns:xmpp-sasl’> <mechanism>DIGEST-MD5</mechanism>
<mechanism>PLAIN</mechanism>
</mechanisms>
</stream:features>
依據數據交換信息指導pemberley.orgserver支持TLS。流壓縮zlib等。
在兩臺服務器間創建xmpp流的過程一樣。但是 jabber:client換成 jabber:server才幹夠。
3).身份驗證
xmpp可以進行tls傳輸層安全加密,並且大多數client默認使用。
server支持tls加密後。client就會啓動tls連接。並將當前套接字升級爲一個加密套接字。
建立一對新的xmpp流。
xmpp身份驗證使用sasl 簡單身份驗證與安全層協議,並支持多種身份驗證機制。server通提供明文驗證和基於md5摘要的驗證,但是某些server還支持經過kerberos或特殊令牌來驗證。
完畢身份驗證後,client必選爲該連接綁定一個資源並啓動一個會話。假設用戶正在線路上查看xmpp流量,就會看到<bind><session>元素被髮送出去。(在<iq>中) 假設client沒有提供綁定的資源,那麼server將爲其選定一個。
當兩臺server相互鏈接的時候,server交換並驗證tls證書。或者接受server使用某種回撥協議經過dns來驗證發送者身份。
4).鏈接斷開
當用戶結束xmpp會話的時候,他們終止會話並斷開鏈接。
最有禮貌的終止會話的方式是:先發送無效出席信息。而後關閉<stream:stream>元素。 經過發送最後的無效出席信息,用戶的聯繫人能夠得知該用戶離開的緣由。 <presence type=’unavailable’/> </stream:stream> 而後,server終止發往client的流。