Fork me on GitHub

XMPP协议原理

本文介绍XMPP协议原理及相关信息。

 

XMPP协议简介  

XMPP(Extensible Messageing and Presence Protocol:可扩展消息与存在协议)是目前主流的四种IM(IM:instant messaging,即时消息)协议之一,其他三种分别为:即时信息和空间协议(IMPP)、空间和即时信息协议(PRIM)、针对即时通讯和空间平衡扩充的进程开始协议SIP(SIMPLE)。

 

在这四种协议中,XMPP是最灵活的。XMPP是一种基于XML的协议,它继承了在XML环境中灵活的发展性。因此,基于XMPP的应用具有超强的可扩展性。经过扩展以后的XMPP可以通过发送扩展的信息来处理用户的需求,以及在XMPP的顶端建立如内容发布系统和基于地址的服务等应用程 序。而且,XMPP包含了针对服务器端的软件协议,使之能与另一个进行通话,这使得开发者更容易建立客户应用程序或给一个配好系统添加功能。

 

1. 什么是XMPP ?

XMPP的前身是Jabber,一个开源形式组织产生的网络即时通信协议。XMPP目前被IETF国际标准组织完成了标准化工作。标准化的核心结果分为两部分; 核心的XML流传输协议 基于XML流传输的即时通讯扩展应用 XMPP的核心XML流传输协议的定义使得XMPP能够在一个比以往网络通信协议更规范的平台上。借助于XML易于解析和阅读的特性,使得XMPP的协议能够非常漂亮。 XMPP的即时通讯扩展应用部分是根据IETF在这之前对即时通讯的一个抽象定义的,与其他业已得到广泛使用的即时通讯协议,诸如AIM,QQ等有功能完整,完善等先进性。

 

2. XMPP的基本网络结构是怎样的

XMPP中定义了三个角色,客户端,服务器,网关。通信能够在这三者的任意两个之间双向发生。服务器同时承担了客户端信息记录,连接管理和信息的路由功能。网关承担着与异构即时通信系统的互联互通,异构系统可以包括SMS(短信),MSN,ICQ等。基本的网络形式是单客户端通过TCP/IP连接到单服务器,然后在之上传输XML。

 

3. XMPP通过TCP传什么了?

传输的是与即时通讯相关的指令。在以前这些命令要么用2进制的形式发送(比如QQ),要么用纯文本指令加空格加参数加换行苻的方式发送(比如MSN)。而XMPP传输的即时通讯指令的逻辑与以往相仿,只是协议的形式变成了XML格式的纯文本。这不但使得解析容易了,人也容易阅读了,方便了开发和查错。而XMPP的核心部分就是一个在网络上分片断发送XML的流协议。这个流协议是XMPP的即时通讯指令的传递基础,也是一个非常重要的可以被进一步利用的网络基础协议。所以可以说,XMPP用TCP传的是XML流。

 

XMPP协议工作原理:

 

 

 

4. XMPP协议地址格式:

 

 

5. XMPP消息格式: 

 

 

 

 

 

 

 

6. 核心的XML流传输协议

基于XML FreeEIM流传输的即时通讯扩展应用

XMPP的核心XML流传输协议的定义使得XMPP能够在一个比以往网络通信协议更规范的平台上。借助于XML易于解析和阅读的特性,使得XMPP的协议能够非常漂亮。

XMPP的即时通讯扩展应用部分是根据IETF在这之前对即时通讯的一个抽象定义的,与其他业已得到广泛使用的即时通讯协议,诸如AIM,QQ等有功能完整,完善等先进性。

XMPP的扩展协议Jingle使得其支持语音和视频。 

XMPP的官方文档时RFC 3920. 

 

7. XMPP应用示例

举个例子看看所谓的XML流是什么样子的?

 
  客户端:<?xml version='1.0'?>
 
  <stream:stream
 
  to='example_com'
 
  xmlns='jabber:client'
 
  xmlns:stream='http_etherx_jabber_org/streams'
 
  version='1.0'>
 
  服务器:<?xml version='1.0'?>
 
  <stream:stream
 
  from='example_com'
 
  id='someid'
 
  xmlns='jabber:client'
 
  xmlns:stream='http_etherx_jabber_org/streams'
 
  version='1.0'>
 
  ...其他通信...
 
  客户端:<message from='juliet_example_com'
 
  to='romeo_example_net'
 
  xml:lang='en'>
 
  客户端: <body>Art thou not Romeo, and a Montague?</body>
 
  客户端:</message>
 
  服务器:<message from='romeo_example_net'
 
  to='juliet_example_com'
 
  xml:lang='en'>
 
  服务器:<body>Neither, fair saint, if either thee dislike.</body>
 
  服务器:</message>
 
  客户端:</stream:stream>
 

  服务器:</stream:stream> 

 

 

以文档的观点来看,客户端或服务器发送的所有XML文本连缀在一起,从<stream>到</stream>构成了一个完整的XML文档。其中的stream标签就是所谓的XML Stream。在<stream>与</stream>中间的那些<message>...</message>这样的XML元素就是所谓的XML Stanza(XML节)。XMPP核心协议通信的基本模式就是先建立一个stream,然后协商一堆安全之类的东西,中间通信过程就是客户端发送XML Stanza,一个接一个的。服务器根据客户端发送的信息以及程序的逻辑,发送XML Stanza给客户端。但是这个过程并不是一问一答的,任何时候都有可能从一方发信给另外一方。通信的最后阶段是</stream>关闭流,关闭TCP/IP连接。 

 

8. XMPP系统特点:

1)客户机/服务器通信模式;(2)分布式网络;(3)简单的客户端;(4)XML的数据格式。 

 

9.通俗解释:

其实XMPP 是一种很类似于http协议的一种数据传输协议,它的过程就如同“解包装--〉包装”的过程,用户只需要明白它接受的类型,并理解它返回的类型,就可以很好的利用xmpp来进行数据通讯。

 

最后,希望转载的朋友能够尊重作者的劳动成果,加上转载地址:http://www.cnblogs.com/hanyonglu/archive/2012/03/04/2378956.html 谢谢。 


 

 

原文: http://ceit.uq.edu.au/content/how-xmpp-works-step-step

XMPP 核心协议 http://xmpp.org/rfcs/rfc3920.html

 

XMPP 要点.

 

  • 1. 客户端(C) 和服务器端(S) 通过TCP连接5222端口进行全双工通信.
  • 2. XMPP 信息均包含在 XML streams中.一个XMPP会话, 开始于<stream> 标签, 并结束于</stream>标签.所有其他的信息都位于这俩标签之间.
  • 3. 出于安全目的考虑, 开始<stream>之后, 后续的内容会被适度的使用 Transpor Layer Security (TLS) 协商传输 和强制性的 Simple Authentication 和 Security Layer (SASL) 协商传输.
  • 4. SASL协商完成后, 一个新的 stream 将会被迅速打开, 它将会更加安全和保密.

 

 

第一步: 打开 stream

Client: 客户端发送打开 stream 的片段到服务器, 请求一个新的 session.
<stream:stream to='example.com' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>
这里 “example.com” 是客户端试图连接的服务器的域名.


Server: Server 返回 XML stream, 以<stream:freatures> 开头, 包含要求 TLS 或者 SASL 协商谈判之一, 或者2个都要求.

  1.  
    <stream:features>
  2.  
    <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'>
  3.  
    <required/>
  4.  
    </starttls>
  5.  
    <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
  6.  
    <mechanism>DIGEST-MD5</mechanism>
  7.  
    <mechanism>PLAIN</mechanism>
  8.  
    <mechanism>EXTERNAL</mechanism>
  9.  
    </mechanisms>
  10.  
    </stream:features>

第二步: 加密和认证.

2.1 如果服务器需要 TLS 交涉.

 

Client: 客户端发送 STARTTLS 到服务器.

 

    <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>

 

Server: 服务器返回消息显示 TLS 已被允许:

 

    <proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>


或者 TLS失败了:

 

 

    <failure xmlns='urn:ietf:params:xml:ns:xmpp-tls'/> </stream:stream>

 

在失败的情况下, 服务器会关闭 TCP 连接.

Client: 如果 TLS 已被服务器正确处理, 客户端发送请求一个新的 session:

    <stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' to='example.com' version='1.0'>

Server: 服务器响应一个 XML stream, 指示是否需要 SASL 交涉.

 

  1.  
    <stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' from='example.com' id='c2s_234' version='1.0'>
  2.  
    <stream:features>
  3.  
    <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
  4.  
    <mechanism>DIGEST-MD5</mechanism>
  5.  
    <mechanism>PLAIN</mechanism>
  6.  
    <mechanism>EXTERNAL</mechanism>
  7.  
    </mechanisms>
  8.  
    </stream:features>

 

2.2 SASL 交涉

 

Client 客户端需要选择一个服务器上有效的认证方式来携带SASL交涉数据, 上面的情况, “DIGEST-MD5“, “PLAIN” 和 “EXTERNAL” 是一些可选项.

“PLAIN” 认证模式是三者之中最简单的了. 它是这样工作的:

Client: 客户端按照自己选择的认证模式发送一个将用户名和密码以base64编码的 stream. 用户名和密码按这种格式组织:

“\0UserName\0Password”.

例如我想以用户名为“mbed@ceit.org”登录, 密码是“mirror”. 那么, 在进行base64编码之前, 用户名和密码按照上面的格式组织为一个新的字符串,“\0mbed\0mirror”, 再进行base64编码, 得到字符串“AG1iZWQAbWlycm9y”.


然后, 客户端发送下列 stream 到服务器.

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


Server: 如果服务器接受了认证信息, 服务器会发回 带 “success” 标签的 stream.

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

或者:

Server: 如果密码和用户名不匹配, 或者上面的base64编码有错误, 服务器发回错误信息的 stream.

    <failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>


“DIGEST-MD5” 认证模式的具体方法可以在这里找到: http://www.ietf.org/rfc/rfc2831.txt.

第三步: 资源绑定(可选)


Client: 客户端要求服务器绑定一个资源(可以理解为客户端的类型, 比如电脑, 手机, Web应用等):

  1.  
    <iq type='set' id='bind_1'>
  2.  
    <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>
  3.  
    </iq>


或者
Client: 客户端自己绑定一个资源:

  1.  
    <iq type='set' id='bind_2'>
  2.  
    <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
  3.  
    <resource>someresource</resource>
  4.  
    </bind>
  5.  
    </iq>


Server: 服务器发回另外一个<iq>片段, 如果“type” 标签的内容是“result”, 说明绑定是成功的, 否则说明绑定失败.

  1.  
    <iq type='result' id='bind_2'>
  2.  
    <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
  3.  
    <jid>somenode@example.com/someresource</jid>
  4.  
    </bind>
  5.  
    </iq>

第四步: 请求一个新的session


在 SASL 交涉完成之后或者可选资源绑定之后, 客户端必须建立一个 session 来开始即时消息发送和接收.

Client: 客户端向服务器发送请求:

  1.  
    <iq to='example.com' type='set' id='sess_1'>
  2.  
    <session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>
  3.  
    </iq>

Server: 服务器发回一个<iq> 片段表明 session 是否成功创建.

创建成功的消息类似于:

    <iq from='example.com' type='result' id='sess_1'/>


如果服务器未能创建 session, 服务器将会回复一个如下消息或者其他类型的错误消息.

  1.  
    <iq from='example.com' type='error' id='sess_1'>
  2.  
    <session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>
  3.  
    <error type='auth'>
  4.  
    <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  5.  
    </error>
  6.  
    </iq>

第五步: 客户端和服务器交换 XMPP 片段

 

如果以上步骤均成功完成, 那么客户端就可以发送 XMPP 片段到服务器和接收 XML stream了.

客户端可以发送 <iq> 片段来向服务器请求 roster 或者其他信息. 并可以使用 <presence> 片段来改变客户端的 presence 状态(比如在线, 离开等)

即时消息和其他的负载可以通过发送 <message> 片段来完成.

 

第六步: 关闭 stream

 

最后, 如果客户端想要结束聊天和关闭 XMPP session, 客户端需要发送一个关闭 stream的片段到服务器.

 

  1.  
    <presence type='unavailable'/>
  2.  
    </stream:stream>

 

然后, 服务器将会改变客户端的 presence 状态为 “Offline” , 并且关闭 和客户端的 TCP 连接.

 


 

XMPP通过TCP传输什么

传输的是与即时通讯相关的指令。在以前这些命令要么用二进制的形式发送(比如QQ),要么用纯文本指令加空格加参数加换行苻的方式发送(比如MSN),而 XMPP传输的即时通讯指令的逻辑与以往相仿,只是协议的形式变成了XML格式的纯文本。这不但使得容易解析,人也容易阅读了,方便了开发和查错。而 XMPP的核心部分就是一个在网络上分片断发送XML的流协议。这个流协议是XMPP的即时通讯指令的传递基础,也是一个非常重要的可以被进一步利用的网络基础协议。所以可以说,XMPP用TCP传的是XML流。

posted @ 2020-10-13 16:54  stardsd  阅读(2074)  评论(0编辑  收藏  举报