xmppmini 項目詳解:一步一步從原理跟我學實用 xmpp 技術開發 3.第一句消息的解碼及解碼的原理

    xmpp 協議的這個名稱就來自於它的消息包格式借鑑了 xml 的格式,但並非咱們常規編程中的那種完整的 xml 信息包。所以就不能用普通的 xml 解碼庫來操做這些消息,通常的狀況下是須要另外開發的,而實際的開發中一般使用第三方庫。但就目前的第三庫現狀來講,能夠說是不怎麼好用,因此咱們來看看如何手工本身進行消息的解碼。html

首先第一句話就是一個坑,以咱們前面提到的從服務器中收到的第一句爲例:程序員

 

<?xml version='1.0'?>

<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' from='xumatomacbook-pro.local' id='675c6847-c13d-4710-9844-d9339e4df087' version='1.0' xml:lang='en'>

 

乍一看上去,你會覺得第一句話是 「<?xml version='1.0'?>」,好咱們開始解碼這句話吧。答案是 NO !這句話是無關緊要的,因此咱們解碼的第一個工做就是判斷起始句是 xml 部分仍是後面的 stream 部分。編程

    實際上咱們的作法是根本不解碼!讀者必定瞠目結舌不敢相信,對的,實際上咱們對 xmpp 協議進行操做根本不須要 xml 解碼器,只使用幾個字符串查找和截取函數就能夠了!服務器

    可以這樣作的根本緣由就在於 xmpp 協議並非完整的 xml 包,實際上它和咱們前面文章中的 SMTP/POP3 協議同樣是服務器與客戶端的一問一答式的問答包(固然也還不徹底是,咱們後面會說到),只是藉助了 xml 的封裝形式而已。socket

在 xmpp 協議中,服務器發出第一句話以後就立刻要發送登陸方法說明包,即函數

<stream:features><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>PLAIN</mechanism></mechanisms></stream:features>

相似於這樣的格式。實際上咱們在操做中直接將它們當作一個包處理就好了,就是說能夠直接忽略掉第一個包,無論它有沒有「<?xml version='1.0'?>」。在編程上就是一直讀取服務器 socket 中的內容,咱們將當前讀取到而沒有處理的內容當作一個字符串(而不是 xml 流),給它一個變量名爲gRecvBuf學習

而後每當 socket 接口上有數據來到事件時就去檢測gRecvBuf 中是否已經包含了字符串「mechanism」,若是有,就說明已經收完了第一個包,服務器告訴咱們能夠發送登陸信息了。僞碼以下:atom

 

if FindStr('mechanism', gRecvBuf) {

  [作登陸的各類動做]

}

 

    但這樣其實也不對!由於,含有「mechanism」並不能說明整個登陸包結束了,還記得咱們前面學習 SMTP/POP3 是如何判斷一個包何時結束了嗎?通常狀況下是判斷是否有「\r\n」,xmpp 協議其實也是判斷是否有某個結束符字符串,只不過這個結束符號不是固定的,而是針對不一樣的命令而不一樣而已!這就是 xmpp 協議操做中最關鍵的部分。實際上不光 xmpp 包括 SMTP/POP3 以及咱們還計劃要解說的 http 協議的操做中最關鍵的就是要找到一個包結束的位置和方法,解決了這個問題就能夠說成功了一大半。spa

而對於咱們如今的這個包,它的結束符號是 「</mechanism>」,這裏就要涉及到 xml 格式的知識了,若是一個 xml 節點中還有子節點的話,它必須包括一個 </[節點名]> 這樣的尾部。因此咱們直接利用這一點,在gRecvBuf 中查找到這個字符串就是它的包尾了。3d

瞭解 xml 格式的讀者可能就會提問說,若是mechanism 節點裏還有mechanism 子節點,這個方法就不行了。沒錯,可是恰好 xmpp 協議中是沒有這種狀況的,因此咱們能夠放心地使用這種方式。其實就算有這種狀況,咱們再作進一步處理便可,只是根據 xmpp 協議的特色,沒有必要那樣作。因此實際上正確的操做僞碼應該是:

 

if FindStr('</mechanism>', gRecvBuf) {

  [作登陸的各類動做]

}

 

這其中要注意的是,查找字符串函數應該是忽略大小寫的。由於節點名是有可能含有大小寫混用的狀況的,出於兼容性的考慮,能忽略大小寫是最好的。

這是很是重要的一個章節,建議你們仔細反覆研究一下,雖然內容很少,但這是咱們整個 xmpp 協議消息包處理的中心思想,很是的關鍵,也很是的簡潔有效。

--------------------------------------------------

版權聲明:

本系列文章已受權百家號 "clq的程序員學前班" . 文章編排上略有差別.

相關文章
相關標籤/搜索