在 Android 上,因为 Google 自己实现的 Android 标配的 GCM (Google Cloud Messaging,原来叫 C2DM) 在国内基本不可用,所以,对于开发者来说,如果需要 Push功能,怎么样选择成为了一个问题。
到目前为止,国内尚没有完全向开发者免费、开放的 Push 服务可用。国外有几家第三方推送服务,但一般都要收费。所以一般来说,国内的开发者不得不考虑自己来搭建 Push服务。
自己构建 Push服务时,一个比较自然的选择就是,基于开源的现在方案来做。
使用 Google或者百度搜索 "Android Push 推送"等关键词,表明已经有不少人研究过。排在前边的是这样几篇文章:
- Android实现推送方式解决方案
- 用androidpn来实现推送
- Android上实现Push
- Android Push Notification实现信息推送使用
上面文章提及的方案里,基本上都提及了一个开源的 Android Push实现: androidpn。
androidpn 它本质上服务器端基于 Openfire,客户端基于 asmack,这二者都最 XMPP IM 开源实现里的二个基本组件,应该说 androidpn 只是把二者更多地结合起来用于做 Push的场景。
本人做过聊天App,愿意在这里,把基于 XMPP开源系统做 IM 的实践经验分享给大家。
我们做聊天类App,比较自然地,刚开始时也是从研究开源的 XMPP IM 系统入手。
先说服务器端选择。Openfire 是一个 XMPP 最古老的开源 IM Server,几乎所有做 IM 的都应该有研究过。但是,它也是最不合适运用到生产的 IM Server,因为:单机并发很有限,集群方案不成熟,代码古老而缺乏及时更新。举个具体的例子:Openfire 的集群组件叫 Connection Manager,但是,你在 Openfire官方网站可以看到,最近一个版本是 2009 年 2 月份发布的。可见,基于 Openfire 实现的 androidpn 的根基是不够稳的。
还有另外二个其实相对好一点的选择: ejabberd, tigase。ejabberd 是用 Erlang语言实现的,懂 Erlang 的用户很少,所以一般不会选。我们当时初步的聊天服务器端选择是 tigase。
tigase 作者维护很活跃,集群测试结果能够支撑比较大的容量,这是吸引我们的地方。但经过实际生产运营情况来看,由于其集群方案实现的复杂性,以及单节点容量的有限,我们对支撑到 50 万用户在集群节点上没有信心,所以在到达 50 万用户之前,赶快自己开发了替代方案。
再来说 XMPP 协议与客户端的问题:对于移动客户端来说,原始的 XMPP 有些复杂而且流量消耗大。XMPP 本质上协议体都在字符串的 xml 结构上,每个协议都量一堆的字符串,xml里还有很多无意义的结构。另外,XMPP为了其灵活性,就登录这个事情都需要有 N 个来回。对于手机客户端很在乎流量与电量来说,XMPP 比较笨重。
我们的作法是:协议格式上改为二进制,协议内容上简化交互,但保留对原始 XMPP的兼容。
androidpn 是开源的 Push 实现,是基于 XMPP 开源组件集成的,它没有为手机应用场景做必要的优化。另外,XMPP 本质上双向 IM 协议,而直接基于 XMPP 来实现 Push 功能,也是没有特别地为 Push 的特点优化的,比如客户端网络连接的策略等。
总结一下以 androidpn 为典型的开源 Android Push 方案会存在的问题:
1)容量大了开源服务器实现顶不住,还是需要自己去改进开源实现,或者完全重新用新方案,开发投入与高成本是不可避免的。
2)协议与实现上如流量消耗、网络连接策略等,不是专门为移动 Push 优化过的,是不经济的。
基于我们团队基于 XMPP开源系统实现聊天App的实践经验,我们得出的结论是,在移动端的 IM场景里,开源方案不是个可用好用的方案。后来我们自己完全重新架构了整套系统。之后,正是基于这套全新架构的 IM 系统,演变出来了极光推送。
极光推送专门为移动场景下的实时 Push 来研发,我们想要去解决国内 Android 开发者没有可用好用的 Push方案的问题,是免费的,完全向普通开发者开放。如果你也有这个 Android Push 的需求,不妨到极光推送官方网站进一步地了解。