XMPP 协议适合用来做移动 IM 么

2014-09-02 10:26:06 +08:00
 jwfing

XMPP 协议是什么

XMPP(Extensible Messaging and Presence Protocol,前称Jabber)是一种以 XML 为基础的开放式实时通信协议,关于它的协议细节,网上已经有太多分析文章,我这里就不再赘述(而且,我也不可能比别人解释的更清楚)。简单来看这个协议,我们只需要知道:

1,XMPP 的三种基本角色:客户端、服务器和网关,通信能够在这三者的任意两个之间双向发生。服务器端同时承担了客户端信息记录、连接管理和信息路由的功能。网关则承担着与异构系统的互联互通功能。在 RFC 3920 XMPP Core 中对 XMPP 网络结构有一个描述:
<pre>
C1—-S1—S2—C3
|
C2—-+–G1===FN1===FC1
</pre>
这里 C1,C2,C3 表示 XMPP 客户端;S1,S2 表示 XMPP 服务器;G1 表示网关,用来负责 XMPP 协议和外部聊天协议的转换;FN1 表示外部消息网络的服务器,FC1 表示外部网络客户端。

大家可能会奇怪,这里为什么需要一个网关呢。这要从 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节点 <stream>;XML Stanza 则定义了实体消息的具体语义单元,在 XMPP 中定义了 3 个顶层消息:

2.1 Presence
用于确定用户的状态。消息结构举例如下(每个 XML 的 node 还会有很多其他 attribute,为了简单起见这里省略,下同):
<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格式进行查询和响应。
<iq from=“abc@jabber.org/contact” id=“id11” type=“result”>
</iq>

3,XMPP 的交互流程。
XMPP 通过 TCP 传输了什么内容?在 QQ 里面,消息是使用二进制形式发送的,在 MSN 里面是采用纯文本指令加参数加换行符的形式发送的,而 XMPP 传输的即时通讯指令与他们相仿,只是协议的形式变成了 XML 格式的纯文本,这让解析更容易,方便了开发和查错,但是也带来了数据负载过重的缺点,而被人广为诟病。

XMPP 聊天的过程如下:

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协议看起来已经落后移动互联网了。

21395 次点击
所在节点    程序员
41 条回复
erylee
2014-09-02 10:40:32 +08:00
嗯,个人觉得XMPP不适合,我们在开发SLIMPP,GitHub项目: https://github.com/slimpp/
chmlai
2014-09-02 10:57:36 +08:00
@erylee 你这个基于 MQTT 的好像不错, 可以问问现在是开发到什么状态了吗?, 留意下;
ioth
2014-09-02 11:12:02 +08:00
关注,现在要做一个。
ahu
2014-09-02 11:16:03 +08:00
注册了下,貌似还不能用
erylee
2014-09-02 11:19:44 +08:00
@chmlai 基础协议刚开发完,比如iOS的CocoaMQTT, erlang的mqtt server。现在开发Android的一个Demo,0.1版本应该在10月发布,然后迭代协议到1.0
a2z
2014-09-02 11:22:16 +08:00
XMPP用的XML,overhead太大了,大部分情况下结构描述比信息本身都大,非常不适合在流量有限的移动环境中使用。
erylee
2014-09-02 11:28:52 +08:00
@ahu 嗯,那个是协议开放站点,还只有web部分,手机端刚开始不久
caoyue
2014-09-02 11:40:47 +08:00
XMPP 协议确实非常蛋疼,但是好处是足够完善,实现也很多,适合快速开发
allenforrest
2014-09-02 11:47:18 +08:00
SIP 也一样,开销非常大。

但我还是很推崇 XMPP,优势在协议完备性、各种实现的成熟度等等方面。

可以考虑在实现层面做一下改造,将 XMPP 报文在底层 TCP 传输时做一次编解码,转换成自定义的二进制格式,只需要改造一下 smack 库和 openfire 源码部分,对于上层应用开发来说完全透明,原来 smack 怎么用还是怎么用。

底层编码后的冗余数据大大减少,节省流量和功耗。

另外,考虑 XMPP 各种协议扩展较多,我们只需要针对最常用、最频繁的 XMPP 报文做编解码即可,其他不常用的仍然维持现有文本格式,对流量的贡献可控。
est
2014-09-02 11:49:45 +08:00
XMPP非常烂。离开了libjingle2的XMPP在桌面上都是一坨废物。
lithiumdroid
2014-09-02 11:52:54 +08:00
丰总,你还在写代码吗丰总
huoxiaochai
2014-09-02 13:00:54 +08:00
MQTT 值得你拥有!
jwfing
2014-09-02 14:30:56 +08:00
@lithiumdroid 哈哈,写啊,我们公司工程师都写代码的。
jwfing
2014-09-02 14:31:46 +08:00
推荐大家考察一下我们推出的聊天服务: https://avoscloud.com/features/realtime-messaging.html
shawngao
2014-09-02 14:43:29 +08:00
哈哈,话说听了上期的teahour,说到AVOS就你一个在做IM,是这样吗?
@jwfing
jwfing
2014-09-02 14:58:35 +08:00
@shawngao 不是不是,我们有一个「小团队」在做 IM,主要负责的工程师是 https://twitter.com/Sunng
shawngao
2014-09-02 15:04:44 +08:00
@jwfing 这样啊,那顺便了解一下你们的IM用C/C++、Golang或者其他?这方面我也是比较感兴趣的,所以想特别了解一下。
pi1ot
2014-09-02 16:04:49 +08:00
xml上面zip一下应该会有改善吧
jwfing
2014-09-02 16:08:23 +08:00
@shawngao 我们服务器端是用 Clojure 写的,整个 AVOS Cloud(http://avoscloud.com) 的后端和网站,都是 Clojure 写出来的:)
shawngao
2014-09-02 16:47:27 +08:00
@jwfing 对的,只是没想到IM也用Clojure, 感谢分享。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/131245

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX