转载自:http://blog.csdn.net/brok1n/article/details/45272573

ddpush: 
首先。ddpush提供了两种连接方式。UDP 和 TCP 官方说明。 UDP比TCP的同时连接数要多很多倍。所以推荐用UDP的方式。 ddpush是用来做推送的。所以说一下。首先ddpush服务器端建立UDP或者TCP服务器。 然后监听服务器的9966端口 UDP 和TCP都是使用这个端口。在这里也顺便说一下。电脑的端口。UDP有的端口、TCP也可有。所以UDP使用9966端口。TCP也可以使用9966端口。TCP的是监听、UDP的是绑定。 没怎么具体看资料。我这说的就是让大家明白。UDP 使用9966端口的同时TCP也可以使用9966端口。 
ddpush服务器监听9966端口之后。客户端用对应的TCP或者UDP连接服务器的这个端口。服务器在收到一个客户端连接的时候。会创建一个客户端的虚拟对象。保存到一个集合里。这个对象里保存了这个对象的uuid(常规来说是md5加密的字符串) 还有这个客户端的网络地址、最后心跳时间、是否有消息需要推送给这个客户端等等一些属性。 
具体可以查看org.ddpush.im.v1.node下的ClientStatMachine.java 这个类。 客户端链接之后。服务器根据这个客户端生成一个ClientStatMachine对象。保存在集合中。 这个集合就是所有连接过服务器的客户端对象集合。这个集合在正常关闭服务器的时候。会被保存到文件中。当ddpush服务器下次启动的时候。就会从文件中读取上次关闭服务器时。保存的客户端对象。

这样 客户端就和服务器端建立了连接、当然这个连接应为各种路由端口映射等问题。需要不时的发送或者接受数据、来告诉路由器这个连接正在使用。避免这个连接被释放。所以ddpush里有心跳机制。 也就是定时 从客户端向服务器端发送消息。如果在一段时间内。服务器没有收到客户端的心跳消息。那么服务器就会认为这个客户端掉线了。 ddpush默认的心跳时间应该是50秒。 大家可以按照自己的需要去修改。

然后我们开始说推送。 ddpush主要是用来从服务器向客户端推送消息。没有从客户端向服务器推送消息。也同时没有客户端向客户端推送消息。 如果有这方面的需要可以自行找解决办法。 当然我这样说。可能有人说 ddpush的客户端也向服务器发送消息。对!是这样的。ddpush的客户端也向服务器发送消息。 
但是: ddpush的客户端向服务器发送的所有消息只有两种类型: 
第一种是心跳消息 
第二种是应答消息

首先第一种消息 心跳消息 这个就不说了。就是为了保持长连接的状态 定时从客户端向服务器发送的消息 
第二种:应答消息 ddpush为了保证客户端接收服务器端推送的消息的到达率 而设计的。 正常情况下 ddpush服务器像客户端推送一个消息。 客户端收到了这条消息 同时将这条消息转发给服务器。服务器接收到了这条转发过来的消息 就知道 这个客户端已经成功的接收到了这条下发的推送消息 然后就把服务器保存的虚拟客户端对象中的 是否有这类消息 设置成 false 如果服务器下发消息之后。没有收到这个客户端反馈的消息。服务器就会在下次接收到客户端心跳的时候 向这个客户端再次发送这条推送消息、直到客户端向服务器发送了响应消息。

好了以上就是ddpush的服务器像客户端推送一条消息的一半的过程。为什么说是一半的。应为我们还没有说 是谁让ddpush服务器向哪个客户端推送消息。下面来介绍一下 怎么告诉ddpush服务器 让ddpush服务器向某个(例如:100001) 用户推送消息

向ddpush服务器发送推送任务的是org.ddpush.im.v1.client.appserver里面的 Pusher.java 这个类。 
里面提供了几种方式 推送0x10消息 推送0x11消息 推送0x20消息 也就是说我们需要用Pusher.java 来告诉ddpush服务器 我要给100001这个用户推送一条 0x10 这种消息 然后ddpush服务器接受到了这个任务。就从 客户端虚拟客户端对象集合中查找这个用户。如果这个用户没有查找到。就根据这条推送消息来创建一个虚拟的用户对象 并存放到虚拟客户端对象集合中 当这个用户登录ddpush服务器之后 ddpush发现服务器已经存在了这个用户。就从虚拟客户端对象集合中把这个用户取出。然后修改这个客户端对象的属性。 同时发现在虚拟客户端对象中有一条需要推送的消息。于是就立即把这条消息推送给这个刚上线的客户端。

这就是怎么告诉ddpush服务器要给谁推送什么样的任务。 
这个向ddpush服务器发布推送任务的过程是 ddpush在启动的时候 同时启动了一个接受推送任务的服务器 这个服务器监听9999端口。 然后 在有要推送的任务的时候。我们创建Pusher.java 这个类的对象。在这个类中。就是连接到ddpush服务器的9999端口。然后 向ddpush发送相对应的数据包。然后ddpush接受到了这个推送任务数据包。检查数据包格式、判断推送任务类型。取出这个推送目标的uuid 从 虚拟客户端对象集合中查找这个uuid 找不到就根据这个推送消息包创建一个 虚拟客户端对象 并将这条推送消息存入这个 虚拟客户端对象中 再把这个对象存到 虚拟客户端对象集合当中。 然后就是上面的过程。 当这个客户端上线的时候。ddpush就发现了有这个客户端对象同时也有一条他的数据。所以这个客户端在上线的时候就会立即收到这条推送消息。

好了基本上ddpush就是这个流程。 同时说一下。ddpush 只能推送最后一条消息给客户端。也就是说ddpush没有推送消息列表 当一条消息被发送到ddpush中 ddpush服务器发送给客户端 如果客户端此时不在线。则肯定是收不到这条推送消息。然后当有第二条消息需要推送给这个用户的时候。 ddpush会抛弃第一个客户端并没有接收到的推送消息。然后开始推送第二条消息。 如果第二条消息客户端也没有收到。并且这时候有第三条或者更多的推送消息需要推送给这个客户端。则ddpush只会保留最后一条推送消息 在这个客户端下次上线的时候 推送给这个客户端。

说了这么多。以上就是ddpush的基本流程。