作者 主題: XMPP初探  (閱讀 1591 次)

0 會員 與 1 訪客 正在閱讀本文。

billy3321

  • 活潑的大學生
  • ***
  • 文章數: 269
  • 性別: 男
    • 檢視個人資料
    • 雨蒼的筆記本
XMPP初探
« 於: 2010-06-03 20:48 »
最近剛好有機會碰到XMPP,把一些學習心得記錄在這邊。
原文網址:
http://billy3321.blogspot.com/2010/06/xmpp.html

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

除了一般通訊協定常有的Server與Client外,XMPP還另外定義了Gateway,
只要通過Gateway,便可以與其他的IM Protocol通話。

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

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

傳輸的內容大致如下:


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

<stream> </stream>所夾住的部份稱為XML Stanza,若是加上<stream> </stream>
本身,則稱為XML Stream。

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

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

引用
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>




一開始兩方先傳送



引用
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