xmppmini 項目詳解:一步一步從原理跟我學實用 xmpp 技術開發 2.登陸的實現

第二章登陸的實現html

 

金庸《倚天屠龍記》windows

  張三丰緩緩搖頭,說道:「少林派累積千年,方得達成這等絕技,決非一蹴而至,就算是絕頂聰明之人,也沒法自創。」他頓了一頓,又道:「我當年在少林寺中住過,只是未蒙傳授武功,直到此時,也不明白尋常血肉之軀如何能練到這般指力。」安全

前言服務器

你們確定不知道,要說其實 xmpp 裏最關鍵、開發中也最很差解決的實際上是登陸過程你信麼?網絡

我要說我只用兩句話就能完成 xmpp 登陸你信麼?jsp

 

2.1 登陸的原理工具

    前面的第一章寫得稍顯囉嗦,下面咱們來實現具體的功能。首先要實現的就是咱們這一節要說的登陸功能。學習

    說來你們也許不相信,其實 xmpp 實現中最難的部分其實就是第一步:登陸。過了這一關以後,其實後面的部分幾乎沒有什麼難度可言,就是些正常的客戶機/服務器應答而已。測試

    登陸部分難就難在其協議的複雜性和兼容性上。和電子郵件同樣,其實登陸過程是有多種實現可選擇的,不過這實際上並無什麼必要所有實現(對於我的開發者來講也不太可能有精力所有實現),就象電子郵件客戶端同樣,咱們實現其中一種最多見的就能夠了,咱們在文章中會解釋爲什麼選擇這種登陸方式。ui

    xmpp 和咱們前面介紹的 smtp/pop3 同樣是以字符串應答爲基礎的,因此也能夠將其交互過程以對話的形式進行描述(固然會有不同的地方,用到時咱們會提到)。具體的與服務器的對話方法咱們在《一步一步從原理跟我學郵件收取及發送》中已經介紹過了,不清楚的同窗能夠移步過去先學習一下,這裏咱們就不贅述了。

 

2.2 創建測試環境

    和電子郵件同樣,要測試咱們的程序和想法須要有一臺可用的服務器,你們能夠直接註冊咱們的 newbt.net 免費郵箱,會自帶 xmpp 功能。xmpp 的完整功能須要您升級爲 1 元包年用戶,不過咱們目前提到的功能在免費用戶級別就能夠完成了(其實咱們的 newbt 免費郵箱和 xmppmini 項目大致上是個衆籌項目,你們以爲有用就支持吧,不會強制收費)。但願本身掌握服務器的同窗也可使用 openfire 服務器搭建,理論上也可使用 ejabberd ,不過在開發中筆者發現 ejabberd 的兼容性要比 openfire 差不少,因此推薦 openfire 。不過對於未來想本身開發服務器的同窗不推薦大家在 openfire 上二次開發,緣由咱們後面會講到(文中若有提到ejabberd 則爲ejabberd-19.08-windows)。

咱們 xmppmini 項目的帳號直接在 http://www.newbt.net:8888 上註冊便可(希望您看到這篇文章的時候咱們項目還健在)。Openfire 須要在http://www.igniterealtime.org/projects/openfire/index.jsp 下載,筆者測試的版本是openfire-4.1.4-1 由於igniterealtime 家的向前兼容性並不怎麼好,因此不能保證與最新版本的 openfire 兼容。Openfire 彷佛不支持多域名,因此在安裝時若是是在局域網中測試,必定要先固定本身的 ip 不然下次開機後就可能沒法鏈接了。

 

2.3 登陸協議與必需要注意的坑

    如前所述咱們只介紹其中一種最經常使用的登陸協議,緣由爲其餘的登陸方式咱們得說上一週並且並不怎麼實用。綜合考慮推薦你們都使用這種登陸方式。在 xmpp 協議中,這種登陸方式稱之爲「PLAIN」。

一般 xmpp 鏈接的是服務器的 5222 端口,雙方對話過程以下:

 

1. 客戶端首先發送信息。

相似於:

<?xml version="1.0"?> 
<stream:stream xmlns:stream="http://etherx.jabber.org/streams" version="1.0" xmlns="jabber:client" to="newbt.net" xml:lang="en" xmlns:xml="http://www.w3.org/XML/1998/namespace">

 

 

服務器的回覆相似於:

<?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'>

 

 

就是這麼簡單的第一句對話,其中也有很容易出錯的兼容性問題。

 

對於 openfire 和 newbt.net 服務器,to 的部分能夠隨便寫。對於 ejabberd-19.08-windows 則必定要寫上正確的對應域名(局域網測試的話則是 IP)

不然會報

<stream:error>

<host-unknown xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>

</stream:error>

</stream:stream>

 

另外,如今 ejabberd 的版本彷佛必定要 ssl 鏈接

可修改 C:/ProgramData/ejabberd/conf/ejabberd.yml 中的 starttls_required 爲 false 不然無法用明文對話進行測試。

能夠看到 xmpp 中收發的字符串並非標準的完整 xml 格式,其實嚴格來講它只是 xml 格式的節點片斷。其中的<?xml version='1.0'?> 並非必須的。瞭解這些在解碼 xmpp 的信息時是很是重要的。

 

2.服務器迴應,而且告知本身的可用登陸方式。

這第一句話的事情還沒完,實際上真實的服務器並不會只回應一條語句,而是會再發送一條語句說明本身支持的功能。相似於:

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

 

因此客戶端發送第一條命令後要有準備,本身要接收兩條迴應信息,若是加上 xml 的信息頭就有多是要接收三條迴應,這和 smtp/pop3/ftp 這樣的傳統網絡協議是不一樣的。

 

3. 客戶端選擇最簡單的 plaint 方式發送相應的用戶名和密碼。

相似於:

<auth mechanism="PLAIN" xmlns="urn:ietf:params:xml:ns:xmpp-sasl">AGNjY0BuZXdidC5uZXQAYWFhYWFh</auth>

 

    這裏有個問題。就是如今對網絡攔截很是重視,理論上有可能會被攔截偷窺到密碼。解決的辦法 xmpp 給出了不少,不用那麼麻煩,咱們選擇最簡單的,直接鏈接 5223 端口就能夠了,除了使用的是 ssl/tls 的通信方式外其餘的不用做任何更改

    發送的消息格式中,紅色之外的部分是固定的,而紅色部分是一個 base64 後的字符串,它的原文爲:」\0用戶名\0密碼」 僞碼以下:

Base64Encode("" + '\0' + user + '\0' + pass)

 

這裏有個超級大坑,在標準協議中這裏其實應該是 「登陸id+字符0+用戶名+字符0+密碼」遺憾的是對這部分協議的理解各家有各家的見解(這種理解上的歧義在 smtp/pop3 中也是很是常見的,也是形成網絡協議實現間不兼容的主要緣由之一)。目前兼容比較好的方式是將「登陸id」直接設置爲空字符串,另外在「用戶名」這裏實際上要帶上它的域名,即「用戶名+@+host」,例如「clq@newbt.net」而不是直接寫上 「clq」。關於這個問題我仔細對比過不少篇同行們的文章教程(rfc文檔更不用說了),大多數做者都沒有解釋這部份內容,但最後他們的給出的代碼中格式大多都是採用留空登陸 id 的方式。也歡迎你們回覆探討這一問題,特別是對  ejabberd 比較熟悉的用戶。目前的現狀是若是寫了登陸 id 的話極可能是過不了 ejabberd 的登陸校驗的。

 

4.服務器迴應是否成功

相似於:

<success xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/>

 

若是登陸失敗的話則相似於:

<failure xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><not-authorized></not-authorized></failure>

 

5.客戶端接收響應,解析出是否成功。

    客戶端只要判斷迴應的消息中包含的是success 仍是failure 就能夠了,連 xml 解碼都用不着。

    因此綜上所述,其實最簡單的 xmpp 登陸其實客戶端只要發送兩句話就能夠了,並且換用安全套接字後就能夠成爲實用的登陸方式。

    這其中的技術難點其實只有一個,那就是服務器迴應消息的解碼,在下一章節中咱們會介紹不使用第三方庫的簡單又實用的方式。

 

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

從本文中你們能夠看出,本系列文章假定你們已經看過《一步一步從原理跟我學郵件收取及發送》系列文章,對於一些通用的操做一筆帶過了(象base64的編碼過程、如何用telnet等工具發送網絡命令行、ssl/tls這些)。也節省了很多篇幅。不過這對於初學者有些不太公平,只有建議這部分讀者先去認真的跟着《一步一步從原理跟我學郵件收取及發送》文章本身動動手先熟悉下網絡程序的經常使用操做。

 

原文出處:https://www.cnblogs.com/-clq/p/12366844.html

相關文章
相關標籤/搜索