DDPush消息推送 网络通讯协议

DDPush消息推送不采用目前流行的XMPP、MQTT等相关协议,而是重新定义了一套自有的、更为简单的二进制网络通讯协议,以连接DDPush服务器与在线终端,以及DDPush服务器与应用服务器。

协议特点

一,DDPush消息推送协议的一个特点是:简单。协议简化了整个三方即时通讯、推送的流程与逻辑,令到DDPush服务器、在线终端、应用服务器三方都大大简化,同时效率提高。

二,DDPush消息推送协议的另外一个特点是:面向二进制数据包。这带来两个好处:一,适用于各种终端(包括Windows、Android、硬件设备等);二,可以基于UDP协议实现,大大提高DDPush的容量和效率。

三,保留最后信息直到确认。DDPush没有消息队列的概念和机制,服务端只保留各种推送信息的类型和最后内容,直至终端主动确认信息处理完成。DDPush不会保存信息的列表。例如应用服务器向某终端推送信息类型A,内容a,由于客户端没有及时收取和确认信息,而应用服务器再次推送信息类型A,内容b,则内容b将覆盖内容a,a被悄悄地丢弃,终端永远无法再从DDPush服务器获得之前的内容a。这个看起来似乎不够人性化,但恰恰符合了DDPush“仅发送控制信息,可能失败,尽可能成功”的理念。

UUID

整个DDPush基于UUID(Universally Unique Identifier)通用唯一识别码来工作。根据uuid全球唯一的特点,DDPush视一个UUID能唯一标识一个终端,不管其来源和任何特性。

UUID由具体的应用自动为每个终端用户生成,应采用UUID规范。DDPush仅接收应用服务器提交的UUID,不接受其他任何标识。UUID是保持和识别在线终端的唯一方式,是推送的核心支撑。

如上所述,可知UUID值一般不应由客户端自动生成,应该通过应用登录功能返回给客户端,客户端再用来连接DDPush服务器。客户端也不应永久保存自身UUID。

具体客户端的UUID并非不可变,应用可根据自身需要改变客户端的UUID,这时客户端需用新的UUID连接DDPush。可变的UUID可认为是一个session key,作用广泛,避免真实用户ID在网络通讯中传输。

推送信息类型

DDPush目前支持3种类型的信息推送:1.通用信息推送;2.分类信息推送;3.自定义信息推送。

  1. 通用信息推送 - 通用信息推送,仅仅发出一个通知信号,告知在线终端“有事情发生需要处理”。但是,该命令不包括任何额外信息(例如信息的类型和内容、发生的时间等),客户端需重新连接到应用服务器检查到底有何任务需执行,或事先定义好该信息对应的处理动作。虽然该命令没有任何额外的信息,但该命令的效率和到达率最高。
  2. 分类信息推送 - 分类信息于通用信息的区别在于:分类信息命令利用8字节64位位运算(|和&),代表最多64种分类信息,扩充了通用信息推送命令。注意,由于该命令是位操作,所以多个分类信息可以同时存在,分次确认。例如有两个分类信息01和10,合并为11。客户端收到信息11后,可能先处理完01,然后向服务器端确认01。这时服务端会清除01的状态位,剩下10,留待下次通知和等待确认。
  3. 自定义信息推送 - 自定义信息的表现为二进制字节数组。应用服务器可提交一个字节数组byte[]和uuid到DDPush服务器,DDPush将会把该字节数组原封不动地发送到uuid对应的终端,不会对字节数组内容做任何的假设、判断和限制(除了数组长度)。因此,该命令作用会非常广泛,可以发送命令、文本、url等各种信息以及它们的结合。事实上,您完全可以扩充该命令内容,实现自己的一套应用协议。

    不过!需要注意的是:DDPush会对该字节数组长度进行限制,长度至少是1,至多不超过500字节!因为过长的内容,会引起很高的UDP丢包率,导致推送失败。大部分网络的MTU少于512字节,因此,少于500字节的信息传输是合适的。再者,DDPush推送的应该是控制信息,绝大部分情况下500字节已经完全足够。

终端 - DDPush消息推送 协议包格式

协议格式:[1字节版本号][1字节appid][1字节命令码][16字节UUID][2字节包内容长度][包内容]

顺序名称代号格式字节描述
1版本号version无符号整数1当前版本号1
2应用IDappid无符号整数1可支持255个应用同时使用一个DDPush服务器,也可以一个应用有255个分类或渠道。注:0保留,用于实时推送
3命令cmd无符号整数1最多可支持255种交互命令,目前只使用了4种
4UUIDuuid无符号整数16128位uuid(注意:服务器下发的指令将不包括此项!)
5内容长度length无符号整数2支持最大65535字节的内容包长度。但udp方式下过大的包长度丢包的机率非常大,DDPush最大内容长度将不会超过500字节,一般为几十字节,提高速度和成功率
6包内容content字节数组1-500与包长度字段数值一致,最少1字节,最大不超过500字节。若包内容长度为0,则不出现此项。

如上所述,客户端上发包头长度是21个字节,服务端下发包头长度是5字节。

注:本文中,版本号和appid都为默认为1 ,实际上可以为其他值。

终端(客户端)心跳包

命令码:0(0x00)。格式:[1][1][0x00][16字节uuid][0x0000]
服务器响应命令码:0(0x00)。格式:[1][1][0x00][0x0000]

DDPush消息推送服务器不对客户端上发心跳包的时间间隔做任何假设和限制,完全由终端自行控制。原因是心跳间隔的控制是一个很复杂的问题,不但和网络类型、网络质量有关,更与具体应用的需求有关。因此,DDPush服务器的运行不考虑客户端心跳时间间隔,但会考虑终端在线状态失效时间(一般为数十个小时以上)

一般来说,更密集的心跳,给推送带来更快更实时的效果,同时给消息推送服务端带来更大的压力和更小的容量,智能设备终端则更加耗电。反之亦然。

重要:DDPush消息推送服务器未必一定响应终端的心跳包,更多的时候服务器是不会响应心跳包的(因为确实没必要),因此,客户端不能依赖服务器的心跳包作为任何逻辑处理的依据。

通用推送命令

命令码:16(0x10)。格式:[1][1][0x10][0x0000]
客户端响应:16(0x10)。格式:[1][1][0x10][uuid][0x0000]

分类推送命令

命令码:17(0x11)。格式:[1][1][0x11][0x0008][8字节无符号整数]
客户端响应:17(0x11)。格式:[1][1][0x11][uuid][0x0008][8字节无符号整数]

注意:分类信息至多64种类型,且按位叠加操作(|和&)进行确认。

自定义信息推送命令

命令码:32(0x20)。格式:[1][1][0x20][0x内容长度][内容]
客户端响应:32(0x20)。格式:[1][1][0x20] [uuid] [0x0000]

注意:内容长度必须与指定的长度一致,并且至少为1,最多500字节,否则被认为是非法格式。

DDPush强烈建议将自定义信息的长度限制为100个字节以内!

应用服务器 - DDPush 协议包格式

应用服务器与DDPush消息推送服务器连接进行信息的推送,仅支持TCP协议,不支持UDP协议。因此,应用服务器发送到DDPush的数据包格式,与终端到DDPush的数据包格式类似,这里不再列出表格,请参考上面的数据格式。

不过,为了减少网络流量,达到更快的速度和效率,DDPush消息推送服务器响应应用服务器的数据格式很简单,只有0和非0,占一个字节,代表提交成功或失败。

通用推送命令

命令码:16(0x10)。格式:[1][1][0x10][uuid][0x0000]
服务端响应:[0|1]。0成功,其他失败。

分类推送命令

命令码:17(0x11)。格式:[1][1][0x11][uuid][0x0008][8字节无符号整数]
服务端响应:[0|1]。0成功,其他失败。

自定义信息推送命令

命令码:32(0x20)。格式:[1][1][0x20][uuid][0x内容长度][内容字节数组]
服务端响应:[0|1]。0成功,其他失败。

要点总结

  1. 基于无序二进制数据包的形式
  2. 基于UUID的标识机制
  3. 心跳包间隔的控制与其响应的不确定性
  4. 控制信息的推送与确认,无消息队列的概念
  5. 基于位操作的分类信息类型
  6. 自定义信息的长度限制与建议