这也算是 一个小广告了,宣传这个DDPush

解决方案 »

  1.   

    个人认为长连接一般可以分宽带互联网、移动互联网、物联网三种场景。
    简单来说:
    一,宽带互联网下,网络比较稳定质量较好,在线客户不多,服务器压力不大的情况下,有接近100%的实时性有效性。
    二,移动互联网下,网络快速切换(坐个公车两三站就切换了),手机频繁休眠唤醒(可能会导致连接失效),会反复断开重连
    三,物联网下,这个要看具体应用。智能穿戴设备可能使用移动互联网(XX手环之类),还有什么儿童手机、一些汽车防盗器也是。智能家具可能使用局域网,工农业、智能城市可能用专线或GPRS之类,情况特定,并且复杂。如果是即时聊天软件的话,QQ是很早就全面基于UDP而不是TCP长连接了。TCP长连接,和普通所谓的短连接(包括HTTP)在网络层是没有任何区别的。所谓长连接,就是连接基本空闲,需要定时发送数据包来维持路由器的端口映射关系老化时间(有人叫NAT表时间之类),以避免端口映射关系超时、端口回收而导致的连接中断。不同路由器的端口映射老化时间是不一样的,并且整个连接中的n个路由器只要其中一个释放端口,都会导致整个连接失效。如果是局域网应用,会简单一些,因为不经过路由器转发数据包。
      

  2.   

    支持一下。正好最近有项目要用到对 Android 做实时推送。也比较了极光、GCM和百度云等三方推送服务。考虑到自建服务一般只有 Androidpn 和 MQTT 可选,两者均有不大不小的问题,看到楼主新发的 ddpush 感到眼前一亮啊。仔细拜读了 ddpush.net 的文档,有一个问题,你强调用 udp 在处理连接上比较合适,而保证消息的可达是应用层的事。这是不是表示,我如果现在用 ddpush  做 android 的集成,那么服务器往手机上推送的消息是不保证能收到的,我还得在客户端收到消息时给服务器一个反馈,如果服务器在超时时间内没收到反馈,得再推送一次消息?不好意思,鉴于时间所限,实现和协议细节没有仔细看,就直接问了。
      

  3.   


    首先谢谢你的关注!简单回答你的问题:不用。网站的描述不太贴切,不好意思,我已经修改了,应该是“不努力保证单次数据包的实时和必然到达,改为可能的多次通知直至终端主动确认,来提高“通知”的最终成功率”。保证推送信息的最终可达是DDPush服务器的责任,“正确消费”信息内容是应用层的事。所以只推一次即可,服务器会等到终端应答确认后才清除信息,否则一直保留。其实,如果终端和推送服务或平台的通讯出了问题,应用服务器再怎么推都是无济于事的,谁都控制不了终端的行为,只能尽量等待其再次活跃。值得注意的是,ddpush有设置信息最大有效时长的,默认50个小时。如果终端50个小时都没上线,信息就会丢弃。你可以更改到十天一百天都可以,只是这样会多消耗内存,因为一般应用都是长期不活跃的终端较多,活跃在线的较少
      

  4.   


    首先谢谢你的关注!简单回答你的问题:不用。网站的描述不太贴切,不好意思,我已经修改了,应该是“不努力保证单次数据包的实时和必然到达,改为可能的多次通知直至终端主动确认,来提高“通知”的最终成功率”。保证推送信息的最终可达是DDPush服务器的责任,“正确消费”信息内容是应用层的事。所以只推一次即可,服务器会等到终端应答确认后才清除信息,否则一直保留。其实,如果终端和推送服务或平台的通讯出了问题,应用服务器再怎么推都是无济于事的,谁都控制不了终端的行为,只能尽量等待其再次活跃。值得注意的是,ddpush有设置信息最大有效时长的,默认50个小时。如果终端50个小时都没上线,信息就会丢弃。你可以更改到十天一百天都可以,只是这样会多消耗内存,因为一般应用都是长期不活跃的终端较多,活跃在线的较少感谢回复。那么,假设我确保终端在线,只是因链路或推送服务端网络的原因导致消息没推送成功,服务端没收到应答信息,多久会重试发送呢,随机延后几十秒或几分钟?换句话说,我要做一个实时性要求比较高的应用(比如IM),用户开着应用,却因为外部网络质量不好导致UDP丢包,应该不会几分钟后才能收到消息吧?
      

  5.   


    首先谢谢你的关注!简单回答你的问题:不用。网站的描述不太贴切,不好意思,我已经修改了,应该是“不努力保证单次数据包的实时和必然到达,改为可能的多次通知直至终端主动确认,来提高“通知”的最终成功率”。保证推送信息的最终可达是DDPush服务器的责任,“正确消费”信息内容是应用层的事。所以只推一次即可,服务器会等到终端应答确认后才清除信息,否则一直保留。其实,如果终端和推送服务或平台的通讯出了问题,应用服务器再怎么推都是无济于事的,谁都控制不了终端的行为,只能尽量等待其再次活跃。值得注意的是,ddpush有设置信息最大有效时长的,默认50个小时。如果终端50个小时都没上线,信息就会丢弃。你可以更改到十天一百天都可以,只是这样会多消耗内存,因为一般应用都是长期不活跃的终端较多,活跃在线的较少感谢回复。那么,假设我确保终端在线,只是因链路或推送服务端网络的原因导致消息没推送成功,服务端没收到应答信息,多久会重试发送呢,随机延后几十秒或几分钟?换句话说,我要做一个实时性要求比较高的应用(比如IM),用户开着应用,却因为外部网络质量不好导致UDP丢包,应该不会几分钟后才能收到消息吧?这些问题问得好。请注意!当前版本的ddpush不会主动重发任何数据包,丢了就丢了,直至收到终端的下一次数据包才回应推送信息包。该策略的目的是节省服务端网络流量不做无头苍蝇。甚至如果终端最后心跳到当前时间已经超过一分钟,ddpush连第一次推送都省了,直接认为终端掉线(原因是本人发现各种网络的端口映射老化时间最短也有一分钟)。因此,主动权在客户端。如果是实时性要求强的IM系统,建议设置ddpush服务器回应心跳包策略为always,代表每次收到终端数据包时都发出心跳包作回应。这样客户端就可以记录自己最后发出数据包和最后接收到回应的时间点,作为是否在线的自我判断。例如,假设业务需求认为30秒无响应则认为断线。那么终端可以每10秒发一次心跳包,然后记录响应包时间。如果发现5秒后未收到回应,则马上再次发送心跳包。当30秒的期限越来越近,可以动态调节每4秒、3秒、2秒发一次心跳。若30秒过去后仍然未收到回应,则认为断线,重新TCP方式登录应用服务器。思想就是动态规划,加上类似tcp的、由客户端控制的重发机制。这里只是举例,实际上你可以设计自己业务的更优算法。当然,目前公布的客户端实现没有实现类似的逻辑,只是简单的发送和等待,这比较适合移动互联网推送的现实情况。你可以继承或重写现有的客户端基类,来达到你要的效果。不过,越精细的控制带来越高的实时性,同时降低整个系统的终端容量,这个是必然的。如果你终端数不超百万的话,也可以考虑用tcp模式,简单可靠,不过要一台好点的2U服务器,我估计自己组装的话不超过2万块就行,内存加多点。
      

  6.   


    首先谢谢你的关注!简单回答你的问题:不用。网站的描述不太贴切,不好意思,我已经修改了,应该是“不努力保证单次数据包的实时和必然到达,改为可能的多次通知直至终端主动确认,来提高“通知”的最终成功率”。保证推送信息的最终可达是DDPush服务器的责任,“正确消费”信息内容是应用层的事。所以只推一次即可,服务器会等到终端应答确认后才清除信息,否则一直保留。其实,如果终端和推送服务或平台的通讯出了问题,应用服务器再怎么推都是无济于事的,谁都控制不了终端的行为,只能尽量等待其再次活跃。值得注意的是,ddpush有设置信息最大有效时长的,默认50个小时。如果终端50个小时都没上线,信息就会丢弃。你可以更改到十天一百天都可以,只是这样会多消耗内存,因为一般应用都是长期不活跃的终端较多,活跃在线的较少感谢回复。那么,假设我确保终端在线,只是因链路或推送服务端网络的原因导致消息没推送成功,服务端没收到应答信息,多久会重试发送呢,随机延后几十秒或几分钟?换句话说,我要做一个实时性要求比较高的应用(比如IM),用户开着应用,却因为外部网络质量不好导致UDP丢包,应该不会几分钟后才能收到消息吧?这些问题问得好。请注意!当前版本的ddpush不会主动重发任何数据包,丢了就丢了,直至收到终端的下一次数据包才回应推送信息包。该策略的目的是节省服务端网络流量不做无头苍蝇。甚至如果终端最后心跳到当前时间已经超过一分钟,ddpush连第一次推送都省了,直接认为终端掉线(原因是本人发现各种网络的端口映射老化时间最短也有一分钟)。因此,主动权在客户端。如果是实时性要求强的IM系统,建议设置ddpush服务器回应心跳包策略为always,代表每次收到终端数据包时都发出心跳包作回应。这样客户端就可以记录自己最后发出数据包和最后接收到回应的时间点,作为是否在线的自我判断。例如,假设业务需求认为30秒无响应则认为断线。那么终端可以每10秒发一次心跳包,然后记录响应包时间。如果发现5秒后未收到回应,则马上再次发送心跳包。当30秒的期限越来越近,可以动态调节每4秒、3秒、2秒发一次心跳。若30秒过去后仍然未收到回应,则认为断线,重新TCP方式登录应用服务器。思想就是动态规划,加上类似tcp的、由客户端控制的重发机制。这里只是举例,实际上你可以设计自己业务的更优算法。当然,目前公布的客户端实现没有实现类似的逻辑,只是简单的发送和等待,这比较适合移动互联网推送的现实情况。你可以继承或重写现有的客户端基类,来达到你要的效果。不过,越精细的控制带来越高的实时性,同时降低整个系统的终端容量,这个是必然的。如果你终端数不超百万的话,也可以考虑用tcp模式,简单可靠,不过要一台好点的2U服务器,我估计自己组装的话不超过2万块就行,内存加多点。非常好,解答了我所有的疑问。基本上,实时性要求高的,需要客户端以心跳回应的策略来响应。 那么我觉得在这种需求的情况下, TCP 模式和长连接对移动终端来说能做到更省电。谢谢!
      

  7.   

    基本上,实时性要求高的,需要客户端以心跳回应的策略来响应。 那么我觉得在这种需求的情况下, TCP 模式和长连接对移动终端来说能做到更省电。
    ----------------------------------------------------------------
    在我自己的测试中,我暂看不出两者耗电的区别,基本一样,我觉得应该不会有大的量级差别。毕竟,TCP的本质实现也是互相回应数据包来保证和确认数据到达的。如果对于给定带宽的网络,在保证质量下,UDP方式也应该能支持更多的终端,因为不需要3次握手连接和4步释放,至少没有前者。TCP3步握手的消耗已经相当UDP方式完成一次“心跳+推送+确认”流程了,而这时TCP才刚刚建好连接。“心跳+推送+确认”,其实本质上就是3次握手!
      

  8.   

    今天刚刚在oschina搜东西的时候看到的,
    还以为是以前忽略掉了这个东西,
    原来是新出的支持一个,
    确实不错。。
      

  9.   


    谢谢支持。baidu的账号?
      

  10.   

    用ddpush推送自定义消息是不是有字数限制的什么的?
      

  11.   

    楼主你好,今天看到你的大作。就马上尝试了一下,果然不错!我的问题是,DDPush对于发送语音消息和传输文件是怎么定义的?还是这个东西暂时没有定义?想请教你这方面的问题!
      

  12.   

    刚刚读了作者的源码,看了几个.java就看不下去了,希望楼主能开个博客详细讲解一下!
      

  13.   

    自定义信息默认500字节,修改配置最多1000个字节,过长的信息失败率会指数级升高。建议只推送标题、id、URL之类,再在客户端通过http或者https读取真正的内容信息。而且,如果信息未接收又有相同类型的新信息到来,旧信息会被覆盖的,这样就丢失了。推送的应该是控制信号,不是内容,更加不应该是多媒体。推标题和url就行。
      

  14.   


    不好意思啊,因为时间精力问题,没办法细细讲解如果有兴趣的朋友又觉得看不懂,建议先看看o'reilly出版的下面三本书
    《Java网络编程》
    《Java线程》
    《Java NIO》
      

  15.   

    自定义信息默认500字节,修改配置最多1000个字节,过长的信息失败率会指数级升高。建议只推送标题、id、URL之类,再在客户端通过http或者https读取真正的内容信息。而且,如果信息未接收又有相同类型的新信息到来,旧信息会被覆盖的,这样就丢失了。推送的应该是控制信号,不是内容,更加不应该是多媒体。推标题和url就行。
    楼主的意思是,我在语音传输的时候,把发送者,语音长度作为一条信息推送到目标用户,当目标用户点击语音消息时,这时通过http请求获取录音播放,是这个意思?
      

  16.   

    自定义信息默认500字节,修改配置最多1000个字节,过长的信息失败率会指数级升高。建议只推送标题、id、URL之类,再在客户端通过http或者https读取真正的内容信息。而且,如果信息未接收又有相同类型的新信息到来,旧信息会被覆盖的,这样就丢失了。推送的应该是控制信号,不是内容,更加不应该是多媒体。推标题和url就行。
    楼主的意思是,我在语音传输的时候,把发送者,语音长度作为一条信息推送到目标用户,当目标用户点击语音消息时,这时通过http请求获取录音播放,是这个意思?
    希望楼主私信我,讲解一下你的源代码!
      

  17.   

    自定义信息默认500字节,修改配置最多1000个字节,过长的信息失败率会指数级升高。建议只推送标题、id、URL之类,再在客户端通过http或者https读取真正的内容信息。而且,如果信息未接收又有相同类型的新信息到来,旧信息会被覆盖的,这样就丢失了。推送的应该是控制信号,不是内容,更加不应该是多媒体。推标题和url就行。
    楼主的意思是,我在语音传输的时候,把发送者,语音长度作为一条信息推送到目标用户,当目标用户点击语音消息时,这时通过http请求获取录音播放,是这个意思?
    希望楼主私信我,讲解一下你的源代码!
    差不多就是这样,为了更好的用户体验,也可以考虑先下载录音后再提示用户。推送的信号是自己的程序接收的,如何处理完全由自己控制。
    代码的话。要不先自己看看客户端代码先吧,应该没问题的