DDPush 任意门消息推送 开源免费实时信息推送服务器

在好几年前,就已经注意到DDPush这款推送中间件,不过看近来发展也还是停留在V1.0的基础上,不免惋惜!恰好最近正在深入研究Java Socket通信编程,也顺带再看看这款应用。官网地址:http://www.ddpush.net/

目录

DDPush 任意门 消息推送

DDPush是什么

DDPush可以做什么

移动互联网消息推送

IM实时消息系统核心组件

物联网设备控制与交互

DDPush消息推送有什么优势

开源、免费

容量高,速度快,要求低

终端设备流量少,省电

DDPush消息推送基于什么技术

DDPush消息推送 概述

IM(Instant Messaging)即时通讯系统

DDPush消息推送的思路

DDPush消息推送的策略

通用终端的支持

使用DDPush消息推送的方式

事情其实很简单

DDPush消息推送 快速开始

第一步:下载DDPush消息推送服务器与Android安卓demo app安装文件

第二步:运行DDPush消息推送服务器

第三步:手机安装与运行Android安卓demo app

DDPush消息推送 一分钟集成

第一步,继承并实现客户端抽象基类

继承UDP或者TCP客户端抽象基类

实现三个抽象函数

public boolean hasNetworkConnection()

public void trySystemSleep()

public void onPushMessage(Message message)

第二步,运行客户端

第三步,应用服务端推送信息

Android客户端

安卓demo apk耗电分析

48小时在线测试结果(UDP,TCP,微信)

DDPush Android UDP Demo 耗电、唤醒次数、唤醒时间详情

DDPush Android TCP Demo 耗电、唤醒次数、唤醒时间详情

微信 耗电、唤醒次数、唤醒时间详情

360省电王评价

耗电小结

DDPush消息推送 网络流量分析

终端上载流量

终端下载流量

服务器流量

小结

UDP对TCP

互联网、移动互联网网络环境

智能终端电池续航能力,系统休眠

IPv4资源、端口资源

端口映射老化时间

服务端承载能力

高级应用网络通讯要求

结论

DDPush 任意门推送 1 下载

系统要求

最新版本1.0.03 (2015-01-02发布)

二进制发布

源码发布

历史版本1.0.02 (2014-08-29发布, 2014-11-21更新android示例工程)

二进制发布

源码发布

历史版本1.0.01 (2014-08-01)

二进制发布

源码发布


DDPush 任意门 消息推送

DDPush是什么

DDPush (Dimension Door Push),任意门消息推送,是一款开源免费的单机千万级实时消息推送服务器,使用Java语言开发,具有简单、稳定、高性能、高容量等特点,适用于互联网、移动互联网、物联网、Android、智能设备、硬件设备等各种环境。

DDPush可以做什么

移动互联网消息推送

DDPush可实时推送信息到各种Android、Windows等手机和平板(即“透传”),并支持双向通信。DDPush支持自定义信息,信息的格式和内容可由开发者自行定义

IM实时消息系统核心组件

通过集成DDPush消息推送,可以开发各种IM实时消息系统,例如:聊天系统、社交App等。

物联网设备控制与交互

DDPush消息推送可作为一个实时控制中心,控制物联网中的各种硬件设备(硬件需支持网络通信),与之双向通信。

DDPush消息推送有什么优势

开源、免费

DDPush采用Apache License Version 2.0开源协议,可放心使用,只要您保留其许可证信息。

容量高,速度快,要求低

DDPush在线部分主要采用UDP协议(同时支持TCP协议),支撑1000万终端在线的服务器,最少只需要4G内存(不考虑变长自定义信息的情况下),单个主流双核CPU使用率低于75%。即:一部普通PC台式机的配置。

DDPush推送部分采取TCP协议和Java NIO非阻塞网络技术,普通PC可支持至少数千台应用服务器同时长连接推送信息到终端,每秒推送信息的速度在1万条以上

终端设备流量少,省电

采用DDPush,智能手机等终端设备在线一个月(空载的情况下),只需几百KB的上载流量,下载流量甚至可调节到为零。

DDPush提供的Android手机App示例demo,连续在线48小时耗电少于0.5 mAh(使用2G网络GPRS连接,经360省电王测试  >>>详情

DDPush消息推送基于什么技术

DDPush基于自有的二进制网络传输协议(基于TCP和UDP),因此客户端可以支持各种类型的终端设备,包括各种智能手机、平板、智能设备、物联网硬件,和各种终端操作系统(包括: Android, Windows, Linux等)。

DDPush使用Java语言开发,因此服务端可运行在各种操作系统和服务器上。

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希望达到的效果,让即时通讯、推送成为家常菜,而不是满汉全席。

DDPush消息推送 快速开始

欢迎来到DDPush快速开始,本页面将引导您快速体验DDPush的基本功能,请按照以下三个步骤操作:
第一步:下载DDPush消息推送服务器与Android安卓demo app安装文件
第二步:运行DDPush消息推送服务器
第三步:安装与运行Android安卓demo app

第一步:下载DDPush消息推送服务器与Android安卓demo app安装文件

请点击以下链接下载文件:
DDPush服务器
安卓客户端app示例(UDP)
安卓客户端app示例(TCP)

第二步:运行DDPush消息推送服务器

解压DDPush消息推送服务器压缩文件到您电脑的某个目录(路径不要包含中文或空格),您将看到2个目录与4个文件。
目录:lib, logs
文件:start.bat, start.sh, console.bat, console.sh

如果您在使用Windows操作系统,请执行start.bat文件(注:勿双击bat文件,请于CMD窗口中运行);如果您使用的是Linux系统,请执行start.sh文件。这里使用Windows系统演示,执行start.bat文件。如果您看到类似以下的信息,说明DDPush服务器已经运行:

DDPush Server Windows Started

您也可以检查logs目录下是否有ddpush.out日志文件输出来判断DDPush是否在运行。此外,您还可检查DDPush的默认端口是否正在监听。

DDPush Server Started Log

如果您要停止DDPush消息推送服务器,请新打开一个命令行窗口,执行命令:"console.bat stop",DDPush服务器将会停止

Linux系统下的操作与Windows类似,差别在于Linux系统下执行的是start.sh和console.sh脚本。
注意:如果您通过ftp单独上传sh脚本文件到Linux服务器,注意不要破坏文件格式,如出现无法运行sh脚本的情况,请尝试使用dos2unix命令转换文本格式,并确保sh文件权限为可执行

第三步:手机安装与运行Android安卓demo app

请使用Android手机分别安装第一步下载的另外两个apk文件。您也可以使用两台手机分别安装,以达到更现实的体验效果

安装完毕后,打开两个app,配置服务器IP为您在第二步中运行DDPush消息推送服务器的机器IP,见下图

DDPush Demo apk udp DDPush Demo apk tcp

按照上图的示例,两个app分别设置不同的用户名,并把目标用户名设置为对方,以测试互相推送信息。这里是user01和user02,各端口号采用默认值。

注意正确设置服务器IP为第二步中DDPush消息推送服务器运行机器的IP,并且手机能正常访问网络与该IP。
分别点击"开始测试"按钮后,即可通过下面的按钮来互相发送推送信息,见下图收到的实时推送信息示例。(若延时数分钟后才收到推送信息亦属正常情况,请检查网络是否畅通,服务器IP地址是否可达)

DDPush Demo apk Notification

当然,您也可以只安装其中一个app demo,然后自己给自己发送推送信息,只要把用户名、目标用户名设置为同一个字符串即可。

>>> demo app耗电吗?

DDPush消息推送 一分钟集成

集成使用DDPush消息推送服务器,只需要简单继承DDPush提供的Java客户端基类,并实现三个简单的函数,即可使用DDPush服务,不需要了解客户端与服务端网络协议交互的细节。

DDPush提供的客户端基类,已经满足大部分的应用场景。此外,DDPush提供的Android App客户端示例,还实现了Android开发中的后台长时间运行的service服务,您可以直接使用。

若DDPush提供的现成基类和示例无法满足您的应用场景,你可以改写或者重写DDPush客户端。这并不会很困难,但需要您了解DDPush自身的网络协议。当然,这个也不会是很困难的事情。

马上开始!

第一步,继承并实现客户端抽象基类

继承UDP或者TCP客户端抽象基类

UDP:public class MyUdpClient extends org.ddpush.im.v1.client.appuser.UDPClientBase
TCP:public class MyTcpClient extends org.ddpush.im.v1.client.appuser.TCPClientBase

实现三个抽象函数

public boolean hasNetworkConnection(){}
public void onPushMessage(org.ddpush.im.v1.client.appuser.Message msg){}
public void trySystemSleep(){}

public boolean hasNetworkConnection()

该函数主要用于智能终端,判断当前是否有可用的网络连接,以达到省电的目的(若无网络连接则不尝试网络操作)。不同的终端检测网络情况的方式会不一样,所以DDPush客户端示例要求您的实现自行判断网络连接是否可用。如果是PC版软件不需考虑省电,可简单返回true,哪怕实际上没有可用的网络连接。

public void trySystemSleep()

该函数同样主要用于智能终端,在客户端不需要发送心跳包,并且服务端无推送信息的时候,尝试系统休眠,达到省电的目的。PC版软件可以直接将该函数留空,不做任何处理。Android则可能要考虑释放WakeLock以进入系统休眠状态。

public void onPushMessage(Message message)

该函数是客户端处理推送信息的业务入口函数。当客户端收到服务端的推送命令,将自动发送确认包,然后调用该函数。所以该函数内或其调用的其他函数,应该确保信息的正确处理,因为正常情况下该推送信息已经确认,极可能不会再次收到通知。

DDPush现成的客户端基类,会在该函数返回后,再调用trySystemSleep()函数。因此该函数内不用考虑保有WakeLock等防止系统休眠的操作。

第二步,运行客户端

UDP客户端:
MyUdpClient myUdpClient = new MyUdpClient(uuid,1,"192.168.1.100",9966);
myUdpClient.setHeartbeatInterval(50);//50秒一次心跳,可由您动态调节
myUdpClient.start();

TCP客户端:
MyTcpClient myTcpClient = new MyTcpClient(uuid, 1, "192.168.1.100", 9966, 5);
myTcpClient.setHeartbeatInterval(50);//50秒一次心跳
myTcpClient.start();

若网络发生变化,客户端会自行处理。
程序退出关闭客户端:myUdpClient.stop()或者myTcpClient.stop()。

第三步,应用服务端推送信息

Pusher pusher = new Pusher(serverIp,port, timeoutMills);
boolean result = pusher.push0x20Message(uuid,message);

注:这个步骤一般应该是应用服务器向DDPush消息推送服务器发起,但在DDPush Android demo工程里面,为了方便直接在客户端调用,只是为了演示如何编程。

Android客户端

在Android App开发中,会涉及到其他特有的因素,例如service的持续运行、WakeLock的控制等,并非简单继承基类实现以上三个函数就能正常工作。请参考DDPush提供的Android客户端示例App

安卓demo apk耗电分析

目前全世界所有智能手机的电池续航能力都是瓶颈,因此app耗电的大小是app开发者非常关注的一个点,特别是长期联网运行的app。

DDPush提供的Android安卓App客户端demo,一方面展示DDPush的使用,另外一个方面也提供了现成的,集成了在线服务的Android开发示例。该示例通过了一系列的长期运行测试,确保在省电省流量方面达到较好的水平。

48小时在线测试结果(UDP,TCP,微信)

以下内容展示了Android demo app在GPRS连接(2G网络)下连续空载运行48小时后的耗电、唤醒时间统计,并与微信作比较。(使用WakeLock Detector和360省电王测试)

ddpush-48h-sys ddpush-48h-wakelock

以上图片显示,GPRS连接(2G网络)下连续运行48小时,DDPush的UDP demo、TCP demo和微信的唤醒次数、总唤醒时间基本持平,在20至25分钟左右。

DDPush Android UDP Demo 耗电、唤醒次数、唤醒时间详情

ddpush-48h-wakelock-udpddpush-48h-power-udp

如图所示,48小时内UDP Demo唤醒605次,唤醒时间21分16秒,耗电0.4 mAh

DDPush Android TCP Demo 耗电、唤醒次数、唤醒时间详情

ddpush-48h-wakelock-tcpddpush-48h-power-tcp

如图所示,48小时内TCP Demo唤醒606次,唤醒时间20分18秒,耗电0.3 mAh

微信 耗电、唤醒次数、唤醒时间详情

ddpush-48h-wakelock-wxddpush-48h-power-wx

如图所示,48小时内微信唤醒721次,唤醒时间25分41秒,耗电0.8 mAh

360省电王评价

ddpush-48h-360sum-udpddpush-48h-360sum-tcp

如图所示,360省电王对UDP和TCP演示app的耗电评价是"此软件耗电极少,适合长期后台运行,请放心使用"
注:360省电王版本为2.2.2.0001

耗电小结

综上所述,在2G网络GPRS连接情况下,TCP与UDP两种方式的耗电基本没差别,并且对手机电池的消耗较少,加上与微信的对比,证明方案可行。

DDPush消息推送 网络流量分析

网络流量,特别是无线电话网络流量,有时候并不是它所应该的那么便宜。即使不考虑价格因素,更快的速度、更高的通信效率这些目标也决定了我们不能无节制地消耗流量,至少不环保。实际上,DDPush从设计的初期开始,就以尽可能少的网络传输作为核心目标。

终端上载流量

根据DDPush当前的通信协议,终端上传的一个UDP数据包,有效数据最少为21字节。加上UDP和IP包的首部长度,不会超过70字节。移动互联网环境下,假设终端每5分钟发送一次心跳包(这个是建议值,过于频繁可能导致智能终端(手机)电池电量消耗过快),则一个月的上载数据量为70x12x24x30=604800字节,约合591K。这就是DDPush客户端所消耗的上载流量(完全空载运行情况下)。

实际情况可能有些不一样,因为当手机处于非休眠状态的时候(智能手机大部分时间都是休眠的),我们可能希望心跳的间隔小一些,以便更及时地收到实时信息,又不至于消耗过多的电(非休眠状态下是非常耗电的,不在乎多耗一些了)。所以,DDPush客户端的上传流量会比上述的591K稍多一些。

终端下载流量

DDPush终端的下载流量远比上传流量少(详见协议内容和使用文档),而且在无信息通知的情况下,DDPush服务器可通过参数配置成不下发心跳,这时将不会有下载流量产生。当然,这种情况下终端可能无法判断自己是否在线。

服务器流量

对于服务器而言,主要的流量是入站流量,这与大部分互联网服务恰恰相反(例如HTTP服务就是典型的入站流量小,出站流量大)。其实这也是IM系统的一个特点。根据DDPush的测试,独享百兆带宽出口(100m bits/second)的网络,可支持一千万以上终端同时在线(5分钟一次心跳,平均每秒3.33万个UDP心跳包,完全是DDPush的能力之内,这时UDP包的成功率将近100%)

什么?独享百兆出口带宽太贵了?拜托,一千万在线客户,您已经是土豪了,就别在乎那一点点带宽费用了......

小结

使用DDPush消息推送,终端设备基本可以忽略DDPush客户端自身的流量;而服务端的流量,相对其收益来说,成本将是非常低的。

UDP对TCP

TCP还是UDP?长连接如何实现?如何实现心跳机制?心跳的间隔如何确定?这些问题都是讨论即时通讯、消息推送等类似话题时,几乎一定被问到的问题。这里尝试正本清源一下。

互联网、移动互联网网络环境

在分析到底应该使用UDP还是TCP之前,有必要先讨论一下互联网与移动互联网的网络环境特点。

互联网的网络基础建设,经过十几年长期的发展,已经较为稳定和成熟,PC终端、操作系统的能力也达到了较高的水平。

而移动互联网,由于涉及到无线电话网络基站、2G、3G和4G技术的不断发展,其稳定性、带宽、资源分配等各方面虽日趋完善,但当前终究还有不少问题的存在。另外,由于移动互联网其“移动”的本质,加上智能终端设备(智能手机、平板电脑)的发展较晚,目前还在不断演变的情况,与互联网相比,移动互联网还是低速、不稳定、终端能力稍弱的情况。而且由于其“移动”本质,短时间内很难达到互联网的质量。

所以,在互联网的环境里面,网络应用程序由于网络设施、操作系统的成熟,开发使用起来比较容易,资源也较为充足。而移动互联网还是要“斤斤计较”。

智能终端电池续航能力,系统休眠

智能终端设备的电池续航能力始终是技术瓶颈。在连续使用的情况下,绝大部分智能设备电池无法支持两个小时以上。所以在没有外部电源的情况,智能终端设备必须频繁、长时间休眠,这将极大地影响两种网络环境下的网络应用场景。

IPv4资源、端口资源

这个话题往往被很多人忽略,但它有着至关重要的影响。虽然大部分人都很清楚IP地址的紧缺导致的动态IP分配的必然,却忽略了由于IP地址不足引起的端口资源不足。

由于需要动态分配IP地址(这里不仅仅指互联网入口的IP,还包括局域网内部的IP),路由器的工作原理都是经过端口映射,把内部网络(包括PC、手机、平板、Wifi、2G、3G、4G)IP与端口映射成外部IP(通常是公网IP)和对应的端口,并维持这个映射关系,才能正常地修改、转发报文信息,保证内部各个ip、端口与外部的各个ip、端口的通信。

然而,单个IP地址的端口资源是有限的,理论上限是65535个端口。对于普通宽带路由器来说,这个已经很充足了。但是!对于大型的网络服务、网络主干接入点等来说,如果IP资源不足,每个IP几万个端口的资源很快会耗尽,从而影响正常通讯。

端口映射老化时间

正因为如此,所有的路由器都会为每个端口映射关系设置老化时间,如果老化时间倒数到0,则端口映射关系失效,该端口被释放给其他连接使用。如果端口全部耗尽,则无法再新建内部与外部的网络连接。

端口映射老化时间,比很多人想象中的要短很多。一般的家用宽带路由器,老化时间一般是两三分钟;在有线宽带运营商接入部分,老化时间可能少于两分钟。在无线电话网络运营商接入部分(例如GPRS连接),老化时间甚至不超过一分钟!

也就是说,任何一个网络通讯(不管是TCP或UDP),如果几分钟之内没有网络报文传输,其占用的IP地址端口将被路由器回收。这个时候该次通信必将终止,不管TCP还是UDP,神马都是浮云。

更残酷的事实是,互联网可认为是由无数个路由器连接而成的,一个网络通信往往需要通过n个路由器,每个路由器都会为一次通信建立自己的端口映射。只要其中一个路由器回收其端口,则整个通讯中断。

这也是很多人疑惑为什么TCP的KeepAlive参数无法保证长连接的原因。TCP的KeepAlive默认是两个小时(而且该参数还是TCP的可选实现,不是必然实现),在路由器端口映射老化时间的影响下,必然无法发挥其作用。实际上,该参数在单一的局域网内才可能被使用上,还要依赖具体的操作系统。

由于路由器端口映射的存在,加上智能终端频繁、长时间的休眠,TCP长连接的实用性在移动互联网情况下极大地打了折扣。

也因为如此,IM系统必须实现所谓的心跳包机制,以保持端口映射关系的老化时间不会减少到0而被回收,从而避免连接中断。

服务端承载能力

不管是UDP还是TCP,最终都是应用服务端的设备去提供服务的。而TCP由于提供了安全可靠的流服务,其对计算机、网络资源的消耗是远远大于UDP协议的。对于配置较好的主流服务器,配备大量的内存(数十G至上百G内存),与高速的磁盘、网卡,是能同时支持数百万个TCP连接的。不过这里需要较专业的服务器设置,需要调整不少系统参数,再加上服务程序的配合。另外,TCP连接的建立、维持与释放,都是需要较昂贵的计算、网络资源的。

终端在线服务,若是一个较为简单的服务,未必使用上TCP众多的高级功能,但承受TCP的昂贵成本,未必值得。如果能用UDP来提供服务,单服务器的承载能力,是可以去到TCP服务的数十倍,甚至上百倍的增长。这也是为什么DNS这种并发数巨大的服务器提供UDP接口的原因。

另外,上百万TCP连接的网络服务,其编程的难度、程序复杂度、调试难度、服务器运维成本、网络成本等都远远高于UDP。

而UDP编程,与上百万个终端通讯的难度与成本则低很多。如果提供的网络服务不是基于流的服务,也允许一定的失败机率(例如P2P),则UDP往往是更适合的方式。

高级应用网络通讯要求

不过,即时通讯系统、推送系统一方面提供终端在线服务,另外一方面也需要考虑内容信息的完整性和安全性。毕竟信息的丢失,或者通讯的被窃听,都是难以接受的。而TCP不管在网络层的可靠性控制,还是在应用层的安全支持(例如HTTPS),都为应用提供无法替代的强大功能和便利。

结论

综合以上所述,其实答案也呼之欲出。

现在的即时通讯系统、推送系统,既面对移动互联网的不确定性,又面对智能终端频繁的系统休眠、网络切换,还要考虑服务端的承载成本,对于在线服务而言UDP是比TCP更适合的方式。但是由于数据完整性、安全性的需要,又不应完全放弃TCP的可靠与安全。

所以,DDPush认为,更恰当的方式应该是:两种通信协议同时使用,各有侧重。UDP用于保持大量终端的在线与控制,应用与业务则通过TCP去实现。这个和FTP服务控制与数据分离,采取不同的连接,有异曲同工之处。

事实上,这个也是即时通讯巨头QQ所采用的方式。早期的时候,QQ还是主要使用TCP协议,而后来就转向了采用UDP的方式来保持在线,TCP的方式来上传和下载数据。现在,UDP是QQ的默认工作方式,表现良好。相信这个也被沿用到了微信上。

简单的考证:登录PC版QQ,关闭多余的QQ窗口只留下主窗口,并将其最小化。几分钟过后,查看系统网络连接,会发现QQ进程已不保有任何TCP连接,但有UDP网络活动。这时在发送聊天信息,或者打开其他窗口和功能,将发现QQ进程会启用TCP连接。

最后,需要明确指出的是:DDPush只专注在保持和控制终端在线方面,而对于具体的应用和业务,DDPush是基本不提供任何支持的。

DDPush 任意门推送 1 下载

欢迎来到DDPush任意门推送下载页面。该页面提供DDPush最新版本的下载链接,也包括旧的历史版本。

注:Android示例工程app中使用到的ddpush相关类库jar包,代码实际是ddpush server中的client部分。

系统要求

Java 6.0或以上

最新版本1.0.03 (2015-01-02发布)

  • 修复了app server端连续推送混合信息时,可能引起的挂起。
  • 客户端tcp超时默认设置改为300秒。
  • 控制台取消仅允许本地网络访问的限制,可远程网络连接控制台。
  • Android示例客户端app无更新。

二进制发布

DDPush Server v1.0.03
安卓客户端App示例(UDP)
安卓客户端App示例(TCP)

源码发布

DDPush Server v1.0.03
安卓客户端App示例(UDP)
安卓客户端App示例(TCP)

历史版本1.0.02 (2014-08-29发布, 2014-11-21更新android示例工程)

  • UDP客户端基类UDPClientBase.java增加getLastReceivedTime()方法,记录服务器最后UDP包时间,可用于IM系统客户端自我判断是否在线或超时
  • 修复了TCP模式下,自定义信息长度较长时引起数据紊乱的Bug。该Bug不影响UDP模式客户端。
  • 2014-11-21更新了android示例客户端,包括TCP和UDP两个工程,解决了部分安卓版本“很抱歉,‘xxxx’已停止运行”的异常提示。

二进制发布

DDPush Server v1.0.02
安卓客户端App示例(UDP)
安卓客户端App示例(TCP)

源码发布

DDPush Server v1.0.02
安卓客户端App示例(UDP)
安卓客户端App示例(TCP)

历史版本1.0.01 (2014-08-01)

DDPush诞生了

二进制发布

DDPush Server v1.0.01
安卓客户端App示例(UDP)
安卓客户端App示例(TCP)

源码发布

DDPush Server v1.0.01
安卓客户端App示例(UDP)
安卓客户端App示例(TCP)

发布了627 篇原创文章 · 获赞 535 · 访问量 359万+

猜你喜欢

转载自blog.csdn.net/boonya/article/details/102847124