XMPP 初探

最近恰好有機會碰到XMPP,把一些學習心得記錄在這邊。html

XMPP(Extensible Messageing and Presence Protocol)是一種IM的通信協定,
其前身爲Jabber,後於IETF標準化爲RFC3920。mysql

除了 ​​通常通信協定常有的Server與Client外,XMPP還另外定義了Gateway,
只要經過Gateway,即可以與其餘的IM Protocol通話。web

XMPP最大的特點在於傳輸的內容。其傳輸的內容爲XML;藉由XML的擴充性,
能夠達到許多的擴展應用。不過也因爲傳輸內容爲XML,所以沒法提供二進制的資料。
檔案傳輸需藉由外部HTTP。若是不可避免,XMPP協議提供了Base64的方式傳輸帶編碼文件。sql

XMPP每一個用戶在網路上都有個獨特的Jabber ID,簡稱爲JID。
JID由id, domain與resource3個部份組成。其格式爲:
id@domain/resource。
resource有時能夠省略。api

傳輸的內容大體以下:服務器


|-------------------- |
| <stream> |
|---------------------- |
| <presence> |
| <show> |
| </show> |
|----------------------|
| <message to="'foo' "> |
| |
| </message> |
|----------------------|
| <iq to="'bar'"> |
| <query > |
| </query> |
|----------------------|
| ... |
|------------ ----------|
| </iq> |
|----------------------|


<stream> </stream>所夾住的部份稱爲XML Stanza,如果加上<stream> </stream> 
自己,則稱爲XML Stream。session

 

presence有點相似於廣播機制,能夠針對有特定subscribe的對象傳送訊息;
message裏的body是傳輸的本文,而iq相似於http的request-responce服務。dom

底下是RFC裏所提供的一個簡單的對話session範例tcp

 

Client: 
<stream:stream to="'example.com'" xmlns="'jabber:client'"
stream="'http://etherx.jabber.org/streams'"
version="'1.0'">
Server :
<stream:stream from="'example.com'" id="'someid'"
xmlns="'jabber:client'"
stream="'http://etherx.jabber.org/streams'"
version=" '1.0'">
... encryption, authentication, and resource binding ...
Client: <message from="'juliet@example.com'"
to="'romeo@example.net'" lang="'en' ">
Client: Art thou not Romeo, and a Montague?
Client: </message>
Server: <message from="'romeo@example.net'"
to="'juliet@example.com'" lang="'en '">
Server: Neither, fair saint, if either thee dislike.
Server: </message>
Client: </stream:stream>
Slient: </stream:stream>

 

 

一開始兩方先傳送svn

 


Client:
<stream:stream to="'example.com'" xmlns="'jabber:client'"
stream="'http://etherx.jabber.org/streams'"
version="'1.0'">
Server :
<stream:stream from="'example.com'" id="'someid'"
xmlns="'jabber:client'"
stream="'http://etherx.jabber.org/streams'"
version=" '1.0'">

 


確立了XMPP通信的開始,然後開始XML Stream的傳輸,
在XML Stream傳輸完了之後結束對話。

XMPP也支援DNS動態解析出Server IP。

標準的XMPP client解析的流程爲(以example.com爲例) 
解析"_xmpp-client._tcp.example.com" ﹐得到鏈接的IP和port; 
若是失敗﹐則解析"_jabber._tcp.timyang.net" ﹐這個主要針對老的服務器設定; 
若是仍是失敗﹐則客戶端認爲domain沒有配置SRV記錄﹐則直接解析"example.com"並使用預設port 5222鏈接。

在瞭解了XMPP的傳輸內容後,接下來就是XMPP伺服器的架設。

咱們以ejabberd爲範例,讓大 家瞭解如何設定ejabberd server。首先安裝ejabberd: 

 

sudo apt-get install ejabberd

 

因爲ejabberd使用erlang所撰寫而成,所以會相依許多erlang的模組;
爾後若是須要讓ejabberd使用MySQL的資料庫,還要上網去抓erlang的相關API。

http://darkrevival.com/blog/2009/05/22/setup-an-xmpp-server/

/etc/ejabberd/ejabberd.pem是ejabberd server的憑證。
若是您有本身的憑證,能夠取代之。
ejabberd的相關設定檔主要在/etc/ejabberd/ejabberd.cfg 
註解爲'%'

其中最重要的有幾項:

設定Admin user:

 

{acl, admin, {user, "", ""}}.

 

例如:

 

{acl, admin, {user, "billy", "localhost"}}.

 

若是須要多個admin user,能夠添加多列。

設定Hostname: 
這邊設定的Hostname就表明這個ejabberd本身的名稱爲什麼。
若是設定爲example.com,那麼billy@example.com 
就是在這臺Server上面認證的。

 

{hosts, [""]}.

 

例如:

 

{hosts, ["localhost"]}.

 


若是有新用戶註冊要提醒誰:

 

{registration_watchers, ["@"]}.

 

例如:

 

{registration_watchers, ["billy@localhost"]}.

 


ejabberd預設是使用本身的資料庫。
如果想要改用MySQL做爲ejabberd的資料庫,
那麼要從mysql,config以及erlang的mysql api三方面下手。

首先加入erlang的mysql api到ejabberd的module目錄底下:

 

svn co https://svn.process-one.net/ejabberd-modules/mysql/trunk mysql 
cd mysql 
./build.sh 
sudo cp ebin/*.beam /usr/lib/ejabberd/ebin

 


再來創建ejabberd專用的database:

 

wget http://svn.process-one.net/ejabberd/trunk/src/odbc/mysql.sql 
mysql -u root -p

 

在mysql中創建ejabberd專用的賬戶

 

GRANT ALL ON ejabberd.* TO 'ejabberd'@'localhost' IDENTIFIED by 'password';

 

創建ejabberd的資料庫

 

CREATE DATABASE ejabberd;

 

匯入mysql的資料庫

 

mysql -D ejabberd -p -u ejabberd <>

 


等到ejabberd設定好上線後,就能夠用ejabberdctl來註冊使用者。

 

sudo ejabberdctl register billy localhost P@ssw0rd

 

以後,就能夠連線到

http://localhost:5280/admin,
若是ejabberd順利執行的話,這邊能夠用admin的id@domain與password登入。

登入後能夠看到各個設定畫面。在這邊也能夠直接註冊使用者。

使用pidgin連線伺服器

pidgin > 新增賬戶

通信協定選XMPP,
使用者填上id,域名填上本身ejabberd server的hostname(或是domain) 
密碼則填上註冊的密碼,成功的話就能夠登入server了。

Python的XMPP模組有很多,而其中最多人推薦的是PyXMPP 
PyXMPP的網站上就有很多範例。
http://pyxmpp.jajcus.net/svn/pyxmpp/trunk/examples/

其中echo_bot.py與send_message.py是很好用的範例。
pyxmpp.all.JID能夠將JID字串組合成物件,
pyxmpp.interfaces.stanza能夠解析許多傳輸的內容。
有興趣的朋友能夠仔細看看。

如下是使用echo_bot.py的結果。

Refrence: 
http://hi.baidu.com/jabber 
http://darkrevival.com/blog/2009/05/22/setup-an-xmpp-server/ 
http://zh.wikipedia.org/zh-tw /XMPP 
http://www.sunbo.name/20080409/xmpp 
http://xmpp.org/rfcs/rfc3920.html

相關文章
相關標籤/搜索