最近刚好有机会碰到XMPP,把一些学习心得记录在这边。

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

XMPP 初探的更多相关文章

  1. WebSocket集成XMPP网页即时通讯1:Java Web Project服务端/客户端Jetty9开发初探

    Web 应用的信息交互过程通常是客户端通过浏览器发出一个请求,服务器端接收和审核完请求后进行处理并返回结果给客户端,然后客户端浏览器将信息呈现出来,这种机制对于信息变化不是特别频繁的应用尚能相安无事, ...

  2. 技术笔记:XMPP之openfire+spark+smack

    在即时通信这个领域目前只找到一个XMPP协议,在其协议基础上还是有许多成熟的产品,而且是开源的.所以还是想在这个领域多多了解一下. XMPP协议:具体的概念我就不写了,毕竟这东西网上到处是.简单的说就 ...

  3. 初探领域驱动设计(2)Repository在DDD中的应用

    概述 上一篇我们算是粗略的介绍了一下DDD,我们提到了实体.值类型和领域服务,也稍微讲到了DDD中的分层结构.但这只能算是一个很简单的介绍,并且我们在上篇的末尾还留下了一些问题,其中大家讨论比较多的, ...

  4. CSharpGL(8)使用3D纹理渲染体数据 (Volume Rendering) 初探

    CSharpGL(8)使用3D纹理渲染体数据 (Volume Rendering) 初探 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharpGL源码 ...

  5. 从273二手车的M站点初探js模块化编程

    前言 这几天在看273M站点时被他们的页面交互方式所吸引,他们的首页是采用三次加载+分页的方式.也就说分为大分页和小分页两种交互.大分页就是通过分页按钮来操作,小分页是通过下拉(向下滑动)时异步加载数 ...

  6. JavaScript学习(一) —— 环境搭建与JavaScript初探

    1.开发环境搭建 本系列教程的开发工具,我们采用HBuilder. 可以去网上下载最新的版本,然后解压一下就能直接用了.学习JavaScript,环境搭建是非常简单的,或者说,只要你有一个浏览器,一个 ...

  7. xmpp

    xmpp学习 下载: Openfire 服务器:Openfire 4.0.2 客户端:Spark 2.7.7 安装 Openfire安装: 根据提示一直下一步,服务器域名设置为:localhost(p ...

  8. .NET文件并发与RabbitMQ(初探RabbitMQ)

    本文版权归博客园和作者吴双本人共同所有.欢迎转载,转载和爬虫请注明原文地址:http://www.cnblogs.com/tdws/p/5860668.html 想必MQ这两个字母对于各位前辈们和老司 ...

  9. React Native初探

    前言 很久之前就想研究React Native了,但是一直没有落地的机会,我一直认为一个技术要有落地的场景才有研究的意义,刚好最近迎来了新的APP,在可控的范围内,我们可以在上面做任何想做的事情. P ...

随机推荐

  1. css3 旋转效果加上双面显示效果

    在学习Css3的过程中,我想做一个类似金字塔,菱形翻页效果,如图这种效果 如是,我自己设计了一个,不带js的旋转效果: 1>第一步我先设计了一个方块,内含一个旋转了45deg的小方块,代码如下: ...

  2. Matlab生成动态链接库供C#调用

    1.首先在Matlab中编写一个或几个.m文件 2.然后在命令空间中输入命令:deploytool 3.修改工程名称,修改需要生成文件后缀 4.添加类,添加文件,然后点击生成.

  3. CPU使用率

    CPU使用率 事故回放 当时的情况是那个样子的: 1,正值饭点,客户电话说系统慢,几乎无法完成订单调度,有时还显示内存不足.当时心里的第一个声音就是,服务器配置太低了,远程一看,2核4G内存,cpu平 ...

  4. Python之print语句

    print语句可以向屏幕上输出指定的文字.比如输出'hello, world',用代码实现如下: >>> print 'hello, world' 注意: 1.当我们在Python交 ...

  5. Codeforces Round #346 (Div. 2) E - New Reform 无相图求环

    题目链接: 题目 E. New Reform time limit per test 1 second memory limit per test 256 megabytes inputstandar ...

  6. asp.net中js和jquery调用ashx的不同方法分享

    代码如下: var xhr = new XMLHttpRequest();            xhr.open("get", 'Controls/gengCart.ashx?C ...

  7. 用CSS截断字符串的两种实用方法

    方法一: 复制代码 代码如下: <div style="width:300px; overflow:hidden; text-overflow:ellipsis; white-spac ...

  8. BZOJ 1741: [Usaco2005 nov]Asteroids 穿越小行星群

    Description 贝茜想驾驶她的飞船穿过危险的小行星群.小行星群是一个NxN的网格(1≤N≤500),在网格内有K个小行星(1≤K≤10000). 幸运地是贝茜有一个很强大的武器,一次可以消除所 ...

  9. [转载]JQuery获取元素文档大小、偏移和位置和滚动条位置的方法集合

    在ajax中经常需要对元素的位置进行精确的定位,此时不仅需要获取元素自身的大小位置等属性.还需要知道页面.浏览器.滚动条等的长度和宽度.因为浏览器的兼容问题,如果使用javascript获取这些数值是 ...

  10. linux grep和正则表达式

    虽然正则表达式经常都在用,但是很少能够静下心来仔细的总结一下.最近看了一个台湾人的网站叫做鸟哥Linux私房菜,关于正则表达式的描述挺详细的.在此,我进行一下总结,如果想仔细的学习正则表达式,请访问鸟 ...