XMPP(Extensible Messaging and Presence Protocol,前称Jabber)是一种以 XML 为基础的开放式实时通讯协议,关于它的协议细节,网上已经有太多分析文章,我这里就再也不赘述(并且,我也不可能比别人解释的更清楚)。简单来看这个协议,咱们只须要知道:node
1,XMPP 的三种基本角色:客户端、服务器和网关,通讯可以在这三者的任意两个之间双向发生。服务器端同时承担了客户端信息记录、链接管理和信息路由的功能。网关则承担着与异构系统的互联互通功能。在 RFC 3920 XMPP Core 中对 XMPP 网络结构有一个描述:程序员
C1----S1---S2—C3 | C2----+--G1===FN1===FC1
这里 C1,C2,C3 表示 XMPP 客户端;S1,S2 表示 XMPP 服务器;G1 表示网关,用来负责 XMPP 协议和外部聊天协议的转换;FN1 表示外部消息网络的服务器,FC1 表示外部网络客户端。sql
你们可能会奇怪,这里为何须要一个网关呢。这要从 XMPP 的来源提及。1996 年 Mirabilis 公司推出了世界上第一个即时通讯系统 ICQ,不到 10 年,IM 就成了最流行的应用之一,MSN、Gtalk、雅虎即时通、AIM、Adium、Pidgin 等各类软件如雨后春笋般涌现,可是这些服务之间没有统一的标准,不能互联互通,XMPP 的设计目的就是为了实现整个及时通讯服务协议的互通,让 IM 成为继 WEB 和 Email 以后的互联网第三大服务。数据库
2,XMPP 的消息格式。服务器
XMPP 协议的全部消息都是 XML 格式的,这是 XMPP 协议的另外一个充满历史意味的选择,想当年 SOA / SOAP 一时间爆发起来,不少消息交换协议都采用了 XML 格式,可是不想 XML 很快就成了「大数据」的代名词。在 RFC 3920 XMPP Core 中定义了两个基础概念,XML Stream 和 XML Stanza,XML Stream 是两个节点之间进行数据交换的容器,它定义了顶层的XML节点
2.1 Presence
用于肯定用户的状态。消息结构举例以下(每一个 XML 的 node 还会有不少其余 attribute,为了简单起见这里省略,下同):session
<presence from="abc@jabber.org/contact" to="def@jabber.org/contact"> <status>online</status> </presence>
2.2 Message
用于在两个用户之间发送消息。消息结构举例以下:并发
<message from="abc@jabber.org/contact" to="def@jabber.org/contact" type=“chat”> <body>hello</body> </message>
2.3 IQ
信息/请求,是一个请求-响应机制,管理XMPP服务器上两个用户的转换,容许他们经过相应的XML格式进行查询和响应。app
<iq from="abc@jabber.org/contact" id=“id11” type=“result”> </iq>
3,XMPP 的交互流程。
XMPP 经过 TCP 传输了什么内容?在 QQ 里面,消息是使用二进制形式发送的,在 MSN 里面是采用纯文本指令加参数加换行符的形式发送的,而 XMPP 传输的即时通信指令与他们相仿,只是协议的形式变成了 XML 格式的纯文本,这让解析更容易,方便了开发和查错,可是也带来了数据负载太重的缺点,而被人广为诟病。性能
XMPP 聊天的过程以下:
XMPP 协议的最主要的一点就是开放,不论是协议、客户端,仍是 Server 端,都有成熟的实现方案。为了实际感觉 XMPP 协议的聊天过程,我使用 asmack library + OpenFire 服务器搭建了一套完整的测试环境。
OpenFire 采用 Java 开发,是一个基于 XMPP 协议 的开源的实时协做服务器,它的安装和使用都很是简单,自带有一个内置的存储数据库(固然,你也可使用独立数据库如Mysql等),并利用 Web 进行管理。其余相似的开源系统还有不少,eJabber、Tigase 也常常被用到。可是根据咱们以前的经验,这些开源系统能支持的并发链接数都不高,要是有超过10万的用户同时连上来,对它们来讲就快达到单机的瓶颈了,这时候通常都须要水平拆分,可是拆分以后服务器之间的 session 同步负担会大幅加剧,对于性能又带来不小的抵消。因此这些系统大都被拿来作研究和测试用,不多见到大规模在生产环境中使用的。
好吧,咱们仍是来实际聊聊看。为了体现真实性,选取了程序员圈子里面较大几率可能发生的几段典型对话:
实际结果以下,我在 Nexus5 上面运行一个 IM app,链接上我本身搭建的 openfire 服务器,而后模拟了上面几段对话,在几个参与者的前提下,消息实时性还挺好,但在系统设置-》网络流量中看到,整个聊天过程当中该 app 消耗掉的网络流量高达 36KB,聊天记录的文本文件大小为 8KB,也就是说网络流量的 70% 都消耗在 XMPP 协议层了,这个数字正好吻合了维基百科上吐槽的数据冗余率。
最后测试下来看,我我的感受是,对于移动互联网来讲,省电、省流量是全部底层服务的一个关键技术指标,XMPP协议看起来已经落后移动互联网了。