DDPush 概述
IM(Instant Messaging)即时通讯系统与信息推送
IM(Instant Messaging)即时通讯系统,从1996年ICQ的出现,到国际巨头割据的今天,已经深刻地影响了互联网,甚至人类社会的变化。从移动互联网时代开始,即时通讯系统更是加剧演变进化,除了iOS和Android提供全世界范围的Push Notification Service,还形成了各种开放的云推送平台与服务,成为巨头厮杀圈地的战场。在可预见的物联网前景下,相信IM即时通讯系统将会进一步进化,成为物联智能时代的IT基础设施之一。
然而,到目前为止,即时通讯(包括其衍生的云推送平台与服务)一直被赋予高难度、高投入的标签,似乎成了强者的专属,普通开发者和中小型IT公司的业务大都依赖现有的第三方产品或服务,先不说可能面临高额的收费,从信息安全角度来说,把自己的客户与业务建立在第三方服务的基础上,也让很多人心存顾虑。虽然业界也有各种较流行的开源实现,但其普及程度还比较低。另外,由于目前的开源实现,普遍基于较高级的应用层面(例如:XMPP),所以其实现较为复杂,普通技术人员不容易掌控和二次开发,并且越高级的应用,其通用性往往越低。
DDPush的思路
DDPush的出发点,是绕过已有的各种门槛和障碍,寻求另外一种简单有效的方法,来尝试折衷地实现移动互联网、物联网时代IM和信息推送需求。DDPush的目的是帮助中小型应用和个人开发者,较容易地跨过IM和推送系统的基本门槛,而不是挑战和取代已有的业界标准和产品。DDPush,任意门推送服务器,只是另外一道门,也许能打开另外一个世界,但绝不是包含整个世界。
DDPush的思路,有点类似MQTT,重新定义了一套较简单和低级的网络通讯协议,来达到更小的流量、更高的效率、以及更好的通用性。而DDPush和MQTT的区别在于,DDPush更为简单,放弃了QoS,只实现极为简单的实时通讯需求,剩下的更多是交由应用层去控制。另外,DDPush实现并主推UDP方式,大为降低网络通信成本和服务器承载成本,提高了容量和效率。
这个特点是DDPush与其他方案一个区别所在。DDPush认为可靠性、完整性,更多是应该由应用层去控制的,而不是网络通信层。理由是在移动互联网、无线物联网的环境下,网络本身就是非常不稳定的因素(至少在很长一段时间内都会是这样),因此不能寄望其能完美地工作,需要应用层的保证。例如:当收到一封邮件的时候,应该是尝试发出一个通知告诉邮箱所有者有新邮件达到,即使通知失败了,也不影响直接登录邮箱查看新邮件,同时也应保留再次通知的可能。设想一下,如果仅仅因为实时通知失败了,就连新邮件都丢失的话,岂不是本末倒置?
DDPush的策略
因此,DDPush采取的策略是:不努力保证单次数据包的实时和必然到达,改为可能的多次通知直至终端主动确认,来提高“通知”的最终成功率。换句话说,DDPush牺牲部分的实时性,来换取更高的成功率,信息可能即时达到,也可能十几分钟后到达,甚至几天后到达(如果终端几天后上线的话),但一般总会到达。(当然,需要实时的时候还是可以实现的,因为DDPush的行为是可配置的,也支持TCP模式)
正因为如此,DDPush主推UDP协议,DDPush的通信协议格式就类似UDP协议,基于包的形式而不是流的形式,不依赖包的顺序。不过,DDPush同时也用TCP实现了相同的协议,有需要的情况下只要打开TCP模式即可。这里需要声明的是:UDP模式的服务器容量,是TCP的几十倍甚至上百倍,请使用者自行权衡。
注:在设计DDPush的早期,作者也曾考虑引入部分QoS的功能,例如重发次数、重发策略等。但最后作者决定放弃大部分QoS功能,把这些问题留给应用层去控制,将更精确更实用,也能大大简化DDPush的复杂度和提高容量与效率。毕竟,业务逻辑由应用层去控制,在线终端的数量由DDPush去保证,各司其职,应该是一种更恰当的方式。就好像邮件是否已读,应该由邮件系统控制,而不是新邮件提醒功能去完成。
不过,DDPush并不是完全没有QoS功能,只是采取了更简单的,和MQTT三种QoS级别都不一样的QoS功能:等待终端确认;外加应用层、终端实现的个性化配合手段,达到更大的自由度。
通用终端的支持
DDPush采取UDP协议的另外一个好处,是对终端设备的通用支持。对于常见操作系统(Windows、Android等)来说,网络操作的支持完全不是问题,只是程序通用性的问题。而对于很多嵌入式Linux系统、普通硬件设备来说,要实现完整的网络通信协议,特别是TCP这种高级应用层协议,是非常困难甚至有时候是不太可能的任务(与芯片、板卡的能力和成本有关),所以是本质的通用性问题。而对于UDP,普通硬件设备和嵌入式系统则能较好地支持,因为其复杂度、难度都低很多,各方面要求也相应降低。DDPush采用二进制网络通信协议,而不是文本协议,这也与很多硬件设备有更多的契合点。这些特点和MQTT很类似,不过目前MQTT协议是基于TCP协议而不是UDP。
使用DDPush的方式
对于XMPP等其他方式,很多开发者习惯直接使用其来传递信息内容。而DDPush提倡传递“控制信息”,类似FTP的工作模式。即:通过DDPush来传递命令和控制信息,真正的内容信息建议终端使用常见的HTTP GET或者新建TCP连接的方式,连接到应用服务器(而不是DDPush服务器)获取。这里还会涉及安全验证、内容有效性等方面的需求,而DDPush不致力于解决类似的问题(MQTT则包括安全验证等规则)。DDPush专注在“通知的下发和确认”方面。
事情其实很简单
DDPush不管是协议本身,还是代码实现,其实都是很简单的。因此,开发者很容易进行改造和二次开发,或者按照自己的需要重新改写。整个DDPush服务器的Java代码量很少,目前只有200K,编译后的二进制文件不到100k,对于大部分开发者来说要读懂,相信并不困难。这也是DDPush希望达到的效果,让即时通讯、推送成为家常菜,而不是满汉全席。