推送简直就是1种轻量级的骚扰方式
自从有了推送,各个公司基本上都在使用推送,这确切是1个比较好的提示方式,Android较iOS强的1个部份,也就是在于Android的Notification。Google教育我们利用好Android的通知模块,做更多友好的交互,可这句话,翻译成中文,不知不觉,就变成了在Notification中推送各种广告,而且仅仅就是1些广告,Notification各种牛逼的功能,完全不需要,这也背背了Google设计Notification的初衷。
更关键的是,现在随意找1款App,没有推送的真是凤毛麟角,更可恶的是,做外卖的App给我推送奥运新闻,1条新闻10几个App推送,以致于现在很多用户都非常反感各种推送广告,就我本人而言,基本上会禁用所有广告类的App的推送。
本人非常反感推送,借用王思聪的1句话,XXX App每天给我推送各种广告,还TM是自己做的推送,真是绝了。
轮询是最简单的与服务器保持通讯的方式,即循环向服务器通讯。这个方案的特点就是通讯由客户端主动发起,你需要自己实现轮询消息队列、频率等等参数,在功耗和效果间做权衡,类似于TCP的短连接。
这个其实就是借助短信来实现信息的展现,只不过把短信内容展现到了Notification中,这个方案,到达率确切高,毕竟短信是比较可靠、稳定的,但劣势也很明显,就是本钱很高,而且在Android平台上,短信的权限比较开放,容易被劫持。
长连接和前面提到的短连接,都是基于Socket连接的方式,他们的区分在与,短连接是每次数据传输终了后就断开连接,而长连接不会。所以,基于轮询的方式,每次都要进行链路的连接,性能消耗更大,基于长连接的方式,就是对这点的改进。利用1旦与服务器连接成功,其实不会主动断开连接,后面的通讯都基于这个通道。目前大部份的推送服务都是基于长连接的推送,在后台保护1个Service,保持利用与服务端之间的TCP长连接。
iOS这边使用系统统1的APNs,所有推送消息都由苹果的服务器进行下发,同时,也由系统进行统1展现和处理。
与iOS1样,Android一样有1套内置的推送方案,但很惋惜的是,Google的服务在中国大陆没法使用,草了个蛋。
专业的第3方推送
手机ROM厂商推送
BAT级别的全家桶
关于第3方推送服务在各个App中的使用率,大家可以参考贾吉鑫的这篇文章:
https://mp.weixin.qq.com/s?__biz=MzA5OTMxMjQzMw==&mid=2648112527&idx=1&sn=b23c1b5f3e32e343ad96d705bd4d63ff
这些推送服务大同小异,基本上1家使用了1个新功能,另外几家,也会很快推出这个功能,就例如之前比较火的,『同享推送通道进行App唤醒』这个技术,友盟、个推推出后,很快其它推送服务商就支持了,所以开发者其实不需要担心哪1家推送功能比较强。
这里还需要说下现在的『推送唤醒』这样1个功能,简单的说,就是所有安装了A推送的App,只要有1个还活着,就能够把其它安装了A推送的App拉起来,从而提高推送的到达率。有些阿里系、百度系的App,被大家称作『全家桶』,实际上就是由于这个缘由,这个方式,确切能在1定程度上提高推送到达率,但另外一方面,也破坏了Android生态,增加了功耗,打乱了系统的清算策略。
另外,小米推送、华为推送,大家接入的缘由可能很简单,就是他们的手机市场占有率比较高,接入他们自家的推送,可以在1定程度上提高到达率,但需要注意的是,推送分为透传和非透传两种方式,透传即我们自己App处理推送消息,而非透传,则是交给相应的PushSDK处理,对小米推送、华为推送来讲,只有采取非透传消息,到达率采取保证,而透传消息,与其它推送并没有甚么区分,换句话说,小米手机、华为手机,只对非透传的推送消息做了可靠性保证,但非透传消息的展现格式非常固定、简单,且不能自定义,这是1个很大的问题,这点应当是很多开发者的误区。
最后,很多推送服务都需要在Application中进行初始化,同时,各种被唤醒策略,又会拉起Application,致使推送进程的重复,所以,这里常常需要对进程名进行过滤,非主进程,不进行初始化。
基本都是基于AndroidPN、MQTT、XMPP、长连接这些方式去实现的,自己搭建Push平台服务,1个最大的问题就是服务真个架构设计,不但本钱高,而且效果不1定好,建议中小企业不要轻易尝试。
1般来讲,类似这类ID都是用于唯1标识利用\用户的,每一个App在每台手机上都会生成1个唯1ID。
Android平台上由于国内存在大量山寨装备,所以很多装备的IMEI、Mac地址、AndroidID 都有可能为空或毛病,所以不能单独作为唯1标识,需要将这些进行组合起来使用。
对利用卸载后RegistrationID的问题,很多PushSDK的策略是,生成1个DeviceID保存到本地存储,利用被卸载后如果被重新安装,如果检测到存储里的DeviceID还在的话,就判定是同1个装备,不重新生成RegistrationID。
这些Key基本都是用于验证App的,每一个包名对应1个加密的Key。
非透传消息是指推送消息被PushSDK获得并处理,透传消息是指推送消息被PushSDK交给宿主利用处理,非透传消息通常只能设置1些固定的样式,比较简单,而透传消息,可以由App自定义处理,比较灵活。
通过利用使用的appid统计用户注册总量。
通过利用使用的appid统计当天的在线用户数。
通过利用使用的appid统计当天在推送平台激活过的用户总数。
在线消息下发数/总下发数。
消息回执数(去重)/消息在线下发数。
到达数/实际下发数。
是指最近3个月内有登录过(装备与推送服务端建立长链接)的装备总数,即有效可下发的用户数。1般的推送服务端认为,装备在100天内没有登录要求,认为该装备已失效,所以无需再次发送。
实际可推送装备数(在消息有效期内,有联网并推送进程正常的装备,即消息有效期内的在线下发数。消息有效期就是设置的离线时间)。
客户端SDK接收到消息的装备数(通过统计客户端SDK接收到消息后的回执取得)。
用自定义非透传消息在用户手机展现过的装备数。
点击通知栏消息的装备数。
那末关于推送,大家实际上最关系的,就是『到达率』。那末这个到达率究竟怎样计算呢?
首先我们举个例子来讲明上面的这些数据背后的实际意义,例如,我们有1款App,有100w的下载量,每一个App启动后,都将上报给服务器1个唯1ID,所以,累计注册量就是100w,也称发送总量。
那末在服务端准备发送推送的时候,当前手机端推送进程还活着的,也就是说推送的长连接还健在的,就是在线装备,如果按天算,那末就叫日在线装备数,我们假定这个数字是60w。
OK,推送发出去后,客户端收到推送消息,并产生回执,代表完成了1次推送,假定这些完成推送的装备是55w,这个就是投递装备数。1般来讲,只要装备在线,基本都能投递,所以这个数字和在线装备数非常接近,不接近的话,这个推送基本就有问题了,其中可能送不达的缘由就在于网络切换等致使长连接断掉这类因素。
那末到这里,1般的推送服务商会使用投递装备数/在线装备数的方式来计算到达率,固然,前面我们也说了,这个比例1定是很高的,如果保持长连接的装备都不能收到推送,那1定是有问题了。
而1般的到达率,应当是投递装备数/可投递装备数,也就是百日内活跃的装备数,这样1除,这个比例1下子就小了很多,由于谁也不知道,这1百天内曾活跃的用户,第2天是否是就已把你卸载了。所以说,Android下统计推送的到达率1般都很低,而推送服务商宣扬的到达率都很高,这其实就是1个偷换概念的问题,我们说的是1般的到达率,而服务商宣扬的是在线到达率。
而且,这个到达率与iOS完全没有可比性,由于iOS统1通过APNs来进行推送,且没法获得到达回执,所以,iOS基本不存在到达率这1说法,如果有,几近也是100%,完全没成心义,所以,如果哪1天有产品或运营跟你说,为何Android的到达率比iOS的到达率差这么多,请绝不客气的砸它1斤苹果。
Tag,或叫标签,是用户的1种属性,在给某些用户设置某类标签后就能够针对推送。比如给喜欢『编程』的人打上『编程』的标签,就能够只给他们精准推送。
通常情况下,1个装备(在1个App里)可以设置多个标签。标签与别名类似,其对应关系也是保存在推送服务器侧的。
Alias,或叫别名,是对已安装某利用的用户取个别名进行标识,在对该用户消息推送时,就能够用此别名来进行推送。设置了别名后,推送时服务器端指定别名便可。推送服务器端来把别名转化到装备ID来找到装备。
Tag和Alias他们的共同点在于,提供对用户的精确推送。
目前大部份的第3方推送服务,都是基于长连接的推送方案,下面将对这个方式进行详细讲授。
首先,我们需要了解下1个网络基本知识——NAT,即网络地址转换(Network Address Translation,NAT),这是由于IP地址是有限的,手机不管是通过路由器还是数据网络,都有1个内网IP地址,同时,路由器上会保护1个外网IP地址,从而构成1个NAT路由表,即内网IP地址:端口,和对应的外网IP地址:端口。这样通过1层层封装与解封装,就到达了内网与外网交换通讯的方式。
由于NAT路由表的大小有效,所以1般路由都有NAT有效期,WIFI下,这个NAT有效期可能会比较长,而在数据流量下,运营商1般都会尽快更新NAT路由表,淘汰无效的装备,所以,在使用数据流量时,长连接常常容易断。
那末除NAT路由表主动淘汰过期的装备以外,切换网络环境和DHCP服务器租期到期,这些情况都有可能致使NAT路由表改变,从而造成长连接中断。
前面我们说了,现在的推送服务1般采取的是长连接的通讯方式,而长连接会由于NAT路由表的更新而中断,所以,客户端会定时向服务端发送1个心跳包,来定期告知NAT路由表,我还活着,别杀我!这就是心跳包的作用——避免NAT路由表超时,同时检测连接是不是被断开。
既然心跳包的作用是避免NAT超时,那末就需要将心跳包的发送频率设置为小余NAT超时的检测频率,而WIFI和数据流量下,对NAT路由表的超时时间又是不1样的,而且不同的网络运营商的超时时间,乃至都不1样,所以,1个比较好的方法就是根据装备当前网络环境,来动态的设置心跳时间。
注意,心跳包与轮询是不1样的,心跳包建立在长连接上,只要发送数据便可,而轮询每次都是1个完全的TCP连接。
既然需要定时任务,那末就需要使用AlarmManager来作定时唤醒了,缘由我之前的文章有讲过,是关于处理器唤醒的缘由,这里就不赘述了,大家可以参考我之前的文章:
http://mp.weixin.qq.com/s?__biz=MzAxNzMxNzk5OQ==&mid=2649484680&idx=1&sn=bd9086a95b769af8d8644cf681ce66ec#rd
所谓进程保活,是指App希望尽量的保证自己的App的推送进程能够存活在后台,以保证可以收到服务真个推送消息,因此,才出现了1大批关于进程保活的方式,例如NDK层的文件锁,fork子进程、前台服务、进程优先级等等方式,但是,这些东西,实际上,都不能完全保证手机的进程管理策略放过你,特别是Android 5.0以后的系统,Android对进程的管理更加严格,还有国内的这些ROM层的修改,ROM想要杀你这个进程,你怎样做也没有办法,哦,除白名单。所以,不要再花心思去找甚么进程保活的黑科技了,好好做好利用,提供用户的使用黏性,才是最好的保活,而对1些产品、运营所谓的『为何微信、QQ都可以保活』这样的问题,我建议你回答它:『如果你能把产品做到微信、QQ那样的数量级,我也能让你活!』
介于各种第3方推送与ROM推送的特点,我们目前采取的推送方案,名为『UniversalPushSDK』,即整合了多个不同的推送渠道,通过模板设计模式来进行整合,并向外暴露统1的接口,这类方式的好处在于UniversalPushSDK利用的各个不同推送特点,提高推送到达率,但是坏处在于,包的体积会大1些。例如,我们现在整合了『小米推送、极光推送、华为推送』,在系统启动的时候,判断当前系统,如果是小米系统,则启用『小米推送』,如果是华为手机,则启用『华为推送』,其它的Android装备,则启用『极光推送』,通过这类方式来设计我们自己的推送SDK,可以在1定程度上,利用好各个推送平台的特性。
那末如果利用这类方式来设计SDK给到不同的App接入,就需要能够将利用的推送Key做到动态配置,这也是我们遇到的最大的1个问题,解决方法大家可以参考我之前写的1篇文章:
http://blog.csdn.net/eclipsexys/article/details/51283232
虽然我极力反对这类方案,我坚持认为,做好App,提升用户使用黏性,才是提升推送到达率的关键
上一篇 c实现set集合