第二章登陸的實現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