XMPP message push实现分析

XMPP message push实现研究

 

XMPP(可扩展消息处理现场协议)是基于XML的协议,它用于即时消息IM)以及在线现场探测。利用该协议可以实现类似QQ那样的实时聊天工具。

优点:

有大量基于XMPP的开源IM应用;

XMPP协议已经被IETF标准化,定义在RFC 3920RFC 3921,以及众多的后续补充协议中。协议相对来说已经比较成熟;

安全性好,XMPPClient-to-Server通信,和Server-to-Server通信中都使用TLS (Transport Layer Security)协议作为通信通道的加密方法,保证通信的安全。任何XMPP服务器可以独立于公众XMPP网络(例如在企业内部网络中),而使用SASLTLS等技术更加增强了通信的安全性;

任何IM供应商在遵循XMPP协议下,都可与Google Talk实现连接。XMPP协议支持不同IM客户端之间互通,例如SMS(短信)MSNICQ

分布式网络架构;XMPP网络的架构和电子邮件十分相像;XMPP核心协议通信方式是先创建一个streamXMPPTCP传递XML数据流,没有中央主服务器。任何人都可以运行自己的XMPP服务器,使个人及组织能够掌控他们的实时传讯体验。

XMPP除了可用在实时通信的应用程序,还能用在网络管理、内容供稿、协同工具、文件共享、游戏、远程系统监控等。

 


缺点:

专门针对push message的开源成熟应用很少;并且大多数采用JAVA,对于资源受限的嵌入式系统,需要自行开发。

协议比较臃肿;对于推送一条消息后就结束和server连接的应用来说,需要额外发送的XMPP信令较多;

XMPP 协议的方式被编码为一个单一的长的XML文件,因此无法提供修改二进制数据。因此,文件传输协议一样使用外部的HTTP。如果不可避免,XMPP协议还提供了带编码的文件传输的所有数据使用的Base64。至于其他二进制数据加密会话(encrypted conversations)或图形图标(graphic icons)以嵌入式使用相同的方法。

开源androidpn目前仅实现了推送给指定用户以及广播两项;还未支持tag多播选项,而tag多播基本上是我们应用主要使用的功能;因此这个功能待开发。

 

1.     协议族

XMPP协议已被IETF标准化,并且已比较成熟;

RFC 3920 XMPP

核心。定义了XMPP 协议框架下应用的网络架构,引入了XML StreamXML 流)与XML StanzaXML 节),并规定XMPP 协议在通信过程中使用的XML 标签。使用XML 标签从根本上说是协议开放性与扩展性的需要。此外,在通信的安全方面,把TLS 安全传输机制与SASL 认证机制引入到内核,与XMPP 进行无缝的连接,为协议的安全性、可靠性奠定了基础。Core 文档还规定了错误的定义及处理、XML 的使用规范、JIDJabber IdentifierJabber 标识符)的定义、命名规范等等。所以这是所有基于XMPP 协议的应用都必需支持的文档。

RFC 3921

用户成功登陆到服务器之后,发布更新自己的在线好友管理、发送即时聊天消息等业务。所有的这些业务都是通过三种基本的XML 节来完成的:IQ StanzaIQ 节), Presence StanzaPresence 节), Message StanzaMessage 节)。RFC3921 还对阻塞策略进行了定义,定义是多种阻塞方式。可以说,RFC3921 RFC3920 的充分补充。两个文档结合起来,就形成了一个基本的即时通信协议平台,在这个平台上可以开发出各种各样的应用。

XEP-0030 服务搜索

一个强大的用来测定XMPP 网络中的其它实体所支持特性的协议。

XEP-0115 实体性能

XEP-0030 的一个通过即时出席的定制,可以实时改变交变广告功能。

XEP-0045 多人聊天

一组定义参与和管理多用户聊天室的协议,类似于Internet Relay Chat,具有很高的安全性。

XEP-0096 文件传输

定义了从一个XMPP 实体到另一个的文件传输。

XEP-0124 HTTP 绑定

XMPP 绑定到HTTP 而不是TCP,主要用于不能够持久的维持与服务器TCP 连接的设备。

XEP-0166 Jingle

规定了多媒体通信协商的整体架构。

XEP-0167 Jingle Audio Content Description Format

定义了从一个XMPP 实体到另一个的语音传输过程。

XEP-0176 Jingle ICEInteractive Connectivity EstablishmentTransport

ICE传输机制,文件解决了如何让防火墙或是NATNetwork Address Translation)保护下的实体建立连接的问题。

XEP-0177 Jingle Raw UDP Transport

UDP 传输机制,文件讲述了如何在没有防火墙且在同一网络下建立连接的。

XEP-0180 Jingle Video Content Description Format

定义了从一个XMPP 实体到另一个的视频传输过程。

XEP-0181 Jingle DTMF

Dual Tone Multi-Frequency

XEP-0183 Jingle Telepathy Transport Method

 

 

 

2.     原理分析

 XMPP message push实现分析_第1张图片

l  XMPP客户端:客户端通过 TCP 连接直接连到服务器,并通过XMPP获得由服务器和任何相关的服务所提供的全部功能;例如MSN,ICQ客户端。

l  XMPP服务器:管理客户端连接/认证/登录,客户端之间的消息转发,保存客户端的用户列表等信息。

l  XMPP网关:实现XMPP协议消息和其他网络协议消息之间的转换,实现XMPP客户端和其他非XMPP客户端(例如MSN客户端)之间的通讯。

 

 

3.     IM聊天应用信令过程简介

这里我们进行Openfire 、Spark客户端、pidgin客户端的交互测试;对应的是类似QQ的两个IM客户端进行实时文字聊天。

Spark客户端运行在linux上,pidgin客户端运行在windows xp上,下面演示两者和Openfire之间的信令交互过程。

 XMPP message push实现分析_第2张图片

 

4.     协议中客户端和server信令流程

从中可以看出开始发送第一条用户消息前,需要进行比较多的信令交互过程。并且客户端需要多次发送初始化流给服务器;

 

步骤

信令举例

备注

1

客户端初始化流给服务器:

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

 

2

服务器发送一个流标签给客户端作为应答:

<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' id='c2s_123' from='example.com'

       version='1.0'>

 

3

服务器发送 STARTTLS 范围给客户端(包括验证机制和任何其他流特性):

<stream:features>

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

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

       <mechanism>DIGEST-MD5</mechanism>

       <mechanism>PLAIN</mechanism>

     </mechanisms>

   </stream:features>

 

4

客户端发送 STARTTLS 命令给服务器:

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

 

5

服务器通知客户端可以继续进行:

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

成功

服务器通知客户端 TLS 握手失败并关闭流和TCP连接:

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

</stream:stream>

失败

6

客户端和服务器尝试通过已有的TCP连接完成 TLS 握手

 

7

如果 TLS 握手成功, 客户端初始化一个新的流给服务器:

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

成功

如果 TLS 握手不成功, 服务器关闭 TCP 连接.

失败

8

服务器发送一个流头信息应答客户端,其中包括任何可用的流特性:

<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'

       from='example.com' id='c2s_234' version='1.0'>

   <stream:features>

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

       <mechanism>DIGEST-MD5</mechanism>

       <mechanism>PLAIN</mechanism>

       <mechanism>EXTERNAL</mechanism>

     </mechanisms>

   </stream:features>

 

9

客户端选择一个验证机制:

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

 

10

服务器发送一个 [BASE64] 编码的挑战给客户端:

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

   cmVhbG09InNvbWVyZWFsbSIsbm9uY2U9Ik9BNk1HOXRFUUdtMmhoIixxb3A9ImF1dGgi

   LGNoYXJzZXQ9dXRmLTgsYWxnb3JpdGhtPW1kNS1zZXNzCg==</challenge>

成功

服务器返回一个错误给客户端:

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

失败

11

客户端发送一个[BASE64]编码的回应这个挑战:

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

   dXNlcm5hbWU9InNvbWVub2RlIixyZWFsbT0ic29tZXJlYWxtIixub25jZT0i

   T0E2TUc5dEVRR20yaGgiLGNub25jZT0iT0E2TUhYaDZWcVRyUmsiLG5jPTAw

   MDAwMDAxLHFvcD1hdXRoLGRpZ2VzdC11cmk9InhtcHAvZXhhbXBsZS5jb20i

   LHJlc3BvbnNlPWQzODhkYWQ5MGQ0YmJkNzYwYTE1MjMyMWYyMTQzYWY3LGNo

   YXJzZXQ9dXRmLTgK</response>

 

12

服务器发送另一个[BASE64]编码的挑战给客户端:

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

成功

服务器返回一个错误给客户端:

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

失败

13

客户端应答这个挑战:

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

 

14

服务器通知客户端验证成功:

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

成功

服务器通知客户端验证失败:

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

失败

15

客户端发起一个新的流给服务器:

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

 

16

服务器发送一个流头信息回应客户端,并附上任何可用的特性(或空的features元素):

<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' id='c2s_345' from='example.com'

       version='1.0'>

   <stream:features>

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

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

   </stream:features>

 

 

 

 

 

 

 

5.     Pidgin客户端和XMPP server建立连接

图片比较多,详细信息请参见如下链接:

http://download.csdn.net/detail/junglefly/9168267

1.     PUSHmessage应用信令过程简介

使用XMPP进行消息推送应用,在网上提到最多的就是androidpn;在信令流程上,和前面实时聊天客户端的基本上是一致的。

详细信息请参见如下链接:

http://download.csdn.net/detail/junglefly/9168267


你可能感兴趣的:(XMPP,消息推送)