XMPP的优点和不足
3月份刚换了工作,入职之后新东家让我负责IM SDK的维护和重构工作。想起8年前曾经也搞过一段时间IM,当时是基于XMPP协议做的二次开发。时间又过了将近十年,时代在发展,技术在进步,如今可以考虑重新研究一下xmpp协议,毕竟这是唯一开源的IM协议,它山之石可以攻玉。
XMPP的特点
闲言少叙,书归正传,我们先来看看xmpp的一些基本特点。
xmpp官方对xmpp的定义是:“XMPP是一种可扩展的消息和状态协议,是一组用于即时消息、状态、多方聊天、语音和视频通话、协作、轻量级中间件、内容联合和XML数据的通用路由的开放技术。”。首先它是一个即时通讯协议,同时也是一种技术,是可扩展的,可以支持文本,语音,视频,多方聊天等等。它的数据载体是XML——这可能是它最被诟病的一点,尤其是移动端用户,我就是其中之一。具体原因我们后面会详述。作为一款开源的协议,它有如下特点:
-
开放——XMPP协议是免费的、开放的、公共的,并且易于理解;此外,多种实现以客户机、服务器、服务器组件和代码库的形式存在,比如openfire(server), smack(client),以及更多,感兴趣的读者可以访问xmpp官网了解更多实现:[XMPP](https://xmpp.org)。
-
标准-IETF已将核心XML流协议正式化为一种经批准的即时消息和呈现技术。XMPP规范在2004年发布为RFC 3920和 RFC 3921,XMPP标准基金会继续发布许多XMPP扩展协议。2011年,对核心RFC进行了修订,形成了最新的规范(RFC 6120、RFC 6121和RFC 7622)。
-
经验证的——第一个Jabber/XMPP技术是由Jeremie Miller在1998年开发的,现在已经相当稳定;数百名开发人员正在开发这些技术,现在有成千上万的XMPP服务器在互联网上运行,数百万人使用XMPP通过公共服务(如Google Talk和XMPP在全球各组织的部署)进行即时消息传递。
-
去中心化——XMPP网络的架构类似于电子邮件;因此,任何人都可以运行自己的XMPP服务器,使个人和组织能够控制他们的通信体验。
-
安全——任何XMPP服务器都可以与公共网络(例如,在公司内部网上)隔离,并且使用SASL和TLS的健壮安全性已经内置到核心XMPP规范中。此外,XMPP开发人员社区正积极致力于端到端加密,以进一步提高安全标准。
-
可扩展——利用XML的强大功能,任何人都可以在核心协议的基础上构建自定义功能;为了保持互操作性,XEP系列中发布了通用扩展,但并不是必须的,如果需要,组织可以维护自己的私有扩展。
-
灵活-除了IM之外,XMPP应用程序还包括网络管理、内容联合、协作工具、文件共享、游戏、远程系统监控、web服务、轻量级中间件、云计算等。可以看出,XMPP这些年也有了很大的发展,从传统的IM协议,已经燕延伸到了云计算领域。
-
多样性——许多公司和开源项目使用XMPP来构建和部署实时应用程序和服务。这些公司和开源项目为XMPP的发展多做出了贡献,这其中可能就包括你我。
以上列举了很多XMPP的好处,下面,我们再来看看XMPP的有哪些短处呢?
-
XML低效
这在前边儿已经简单提过了,应该是XMPP最为人诟病的一点。XMPP里所有的报文都是XML, 在XMPP里称为Stanza, XML可读性可扩展性都很好, 但数据冗余较大, 相同大小的报文能承载的有效数据量较少。这一点使其尤其不适应移动端应用。那么不用XML用什么呢? 其实有很多选择, 基于文本的有JSON, 基于二进制的有protobuf, MQTT等. 如果希望保密, 可以定义私有的PDU。protobuf是google提供的一个开源序列化框架, 类似于XML/JSON这样的数据表示语言, 但是基于二进制, 因此protobuf比XML/JSON都高效短小得多. 虽然是二进制数据格式, 但protobuf仍然具有非常好的扩展性和兼容性。 -
f登录步骤太多
XMPP的标准登录流程有如下交互:
TCP连接
1.1 SRV lookup
1.2 DNS to IP address
1.3 建立TCP连接 - 3步握手建立连接
Open Stream
2.1 Client要求open stream
2.2 Server返回stream响应
2.3 Server返回stream:features
TLS协商
3.1 Client开始starttls
3.2 Server返回proceed
3.3 建立TLS连接 - 4步握手(client hello, server hello, client key exchange, finish)
3.4 重走步骤2里的3步
SASL
4.1 Client发送认证信息
4.2 Server返回认证成功
4.3 重走步骤2里的3步
Resource binding
5.1 Client发送要求resource binding
5.2 Server返回绑定成功
Create session
6.1 Client发送要求创建session
6.2 Server返回成功
登录步骤之所以这么多, 一个原因是XMPP先构建于TCP之上, 然后再建立TLS连接, 而不是直接构建于TLS-over-TCP之上, 另一个原因是为了保证XML streaming的逻辑完整性。
如果使用自有协议, 一个最精简的登录过程可以只需要1.1, 1.2, 1.3, 3.3, 4.1, 4.2, 可以大大减少登录步骤, 差不多可以减少15次左右的TCP交互, 假设一次TCP的RTT为200ms, 那么就可以差不多节省3秒, 实际应用中手机网络更差的话, 需要的时间可能会更多. 尤其是手机经常断网或前后台切换的话, 快速登录或快速resume就非常有必要了。 -
每次登录后请求roster list
如果你的roster list超过几百人, 对应的XML就会比较大, 每次登录后都要获取完整roster list的话会非常影响性能。 -
复杂的presence
XMPP是有Presence的, TCP长连接的状态决定了Client是否在线, 为了避免假连接, 频繁掉线重连干扰用户体验等, 需要维护好TCP的长连接, 定时heartbeat, 要有断网重连机制(用户无感知)等等。
另外, XMPP里的Presence业务逻辑也比较复杂, 包括RFC 6121里的Basic Presence, 还有MUC presence, Temp Presence等, 为了实现Presence, Client和Server都增加了非常多的复杂度。对于mobile-first的IM产品, 都是假设用户时刻available的, 对于用户来说最重要的是聊天列表, 传统IM的Presence并不重要, 譬如微信就没有Presence。 -
后台数据交互消耗电量
手机app进入后台后, 如果有机会保持TCP长连接, 这时与Server之间的数据交互仍然保持不变的话, 大量的数据交互会很快消耗手机电量。
以上对XMPP做了简单的概述。XMPP因为自身的开放,保准,可扩展,灵活等特性,吸引了不少的用户,也使自身一直得到了持续的发展。但是因为协议本身以及数据载体(XML)的限制,使其在性能和效率方面不是尽如人意,在移动端尤其明显。大家可以根据自身的需要做取舍,选择XMPP或者其它方案,或者对XMPP进行裁剪,优化,毕竟,它是开放的,这是它的最大优势。