原文
导读
本文旨在对手机推送原理进行剖析和阐述,对业务开发做一些方向性的解惑。
一、基本概念
什么是手机推送?
手机推送服务是指服务器定向将信息实时送达手机的服务
这里有两组概念:
- 第一组是 “服务器” 和 “手机”,说明了一条推送消息是从哪里启动(服务器),到哪里是终点(手机);
- 第二组是 “定向” 和 “实时”,说明推送是可以指定接受者的,并且到达的速度非常快!
我们平时所说的 “推送”, “通知”, “app 推送”, “推送服务”,“通知消息”,“通知栏消息” 等等,指的都是同一个。
样式在苹果和安卓手机的不同
1.苹果手机中的样式
2.安卓手机中的样式
二、推送原理
由于移动网络的限制,服务器并不能在没有连接的情况下主动发送信息到移动端。所以推送本质上都是由手机设备发起,与推送服务器建立起连接通道(TCP长连接),通道就是保障推送到达的关键。
在iOS系统中,推送服务器是由苹果公司维护,所有的应用均使用Apple 推送通知服务 (APNs) 来实现。
在android系统中,海外有谷歌的GMS,用于推送。GMS全称为GoogleMobile Service,即谷歌移动服务。当然由于众所周知的原因,国内是使用不上的。
APNs和GMS的推送原理基本一致,通过系统建立推送通道,所有应用均使用该通道,推送信息由该通道进行分发:
其中系统接受到推送消息有两种可做的行为,一种是通知,一种是透传。
通知:系统只负责弹出下拉栏列表,需要用户点击才能唤醒应用。
透传:系统将信息投递给相关的应用,应用实时收到信息,可以进行业务逻辑,前提是应用未被杀死。
他们的关系如下:
iOS 系统由于国内可用 APNs 服务,所以到达率相当稳定。而 android 系统没有统一的推送,导致发展较为缓慢,大致可以分为三个阶段:
国内安卓推送的三个阶段
1.混沌期
Android早期版本对于app限制极少,app可以在后台一直活着,甚至被杀还能被自动拉起。这时候很多app建立了自己的长连接推送:
这时候自建推送的技术门槛还是挺高的,维护成本也高,用户体验也不好,经常出现性发热卡顿等情况,还会偷偷的上传用户行为,毕竟这和植入一个木马区别也不大。
2.门派林立期
随着 android 系统权限的收缩,很少有应用可以在后台活着了,很多应用根本就活不久。加上这时候各大厂已经形成了自己的体系,比如企鹅系,阿里系等等,大厂间的基础设施逐渐完善,应用活不久没关系,只要用户用了派系中的一个还是可以相互唤醒的。
而其他应用则可以抱团使用第三方的推送,第三方也可以实现使用同一推送来相互唤醒:
3.厂商掌权期
随着 android 版本的进一步提升,厂商们开始考虑各种用户体验问题,唤醒链也不好使了。为了电量和性能,app 的生存现状堪忧。
第三方的如极光百度推送自建的推送越来越难到达了。各大手机厂商推出了自己的系统推送服务,扮演起了如苹果般的角色。
到了这个时候,推送的原理已经APNs基本一致了。
有些厂商比较有野心,像小米除了自家的系统推送外,也支持别的手机,但是此时它的工作原理就和极光一样,实现的是第三方推送了,所以到达率也和薛定谔的猫差不多,时灵时不灵。
小结
到现在为止,国内拥有自主厂商通道主要有华为、小米、oppo、vivo、魅族,这几家合计占据85%以上的android市场份额,接入这几家厂商推送,可以保障大部分的机型推送能到达,至于其他小众品牌,只能依赖第三方推送,第三方推送大家起点都一样,能否到达就有点看缘分了。
推送能到达,不一定就能满足业务场景,像网络电话直接唤起应用的场景,在应用死亡的情况下,还是做不到的。
当然也有例外,比如微信支付宝等:
加油把自己 app 做到亿级用户,你也能有这样的特权!
三、业务实践
那么一个业务如何实现接入自己的推送呢?
简单描述一下大致的流程:
1、推送都会生成一个设备 ID,这个设备 ID 在一段时间内维持不变。在 app 启动的时候应该就可以获取到。
2、将这个设备 ID 和用户绑定起来,做映射关系。
3、业务推送到用户的时候,就转换成设备 ID 访问厂商推送接口。
4、厂商推送将信息送达用户。
注意点:
1、厂商推送接口一般为 http 接口,每次访问有设备数量限制,而且有些还有调用频率限制,一个好的实践是异步批量调用,队列+切片是常用的做法。
2、有些厂商会提供回调接口,用来反馈到达的情况,可以看情况使用。
准备工作:
iOS:需要推送证书,在苹果的开发者平台向苹果公司申请,使用时候证书和代码实现要在一起。
Android:各个平台要求不一样,大致如下:
可能遇到的问题:
推送收不到!
推送收不到分为2种情况,一种是从来没有收到过推送;一种是原本推送服务使用正常,突然收不到推送了!
对于前者,一般在程序开发阶段就能解决问题,相对比较简单; 对于后者,情况就复杂一些了。针对后者出现的情况,需要做如下方向上的排查:
手机能否联网,网络是否通畅?无网时是不能收到推送的。
手机系统近期是否有发布新的版本,用户更新到了新的版本?如果是,则可能需要对新版本做适应性的配置。
APP 的代码,和服务端的代码,近期是否有与推送功能相关的改动?如果有,请排查代码影响。
iOS 推送证书的有效期长度一般为1年,在申请时即可看到过期时间!如果使用了第三方服务,第三方仅可以保管证书,不能更新证书。因此推送证书过期后需要重新申请新的证书,并上传到第三方。
部分第三方服务提供者,在证书过期时未能给到明显的提示。该问题的在排查时也比较隐蔽,不易发现,因此需要多加注意。
若使用了三方的付费服务,也应该检查余额是否充足,欠费时推送服务会被停止。不过相对于证书过期问题的提示,欠费的催缴提示会格外明显,基本不可能被忽略!比如发送多份提醒邮件,或第三方客服直接给相关的负责人打电话提醒需要充值续费 。
如果以上情况经过排查后均没有问题,则需要考虑一些不常见的场景和偶发性的情况,包括但不限于如下所述:
用户对手机进行了恢复出厂设置,之后尚未允许授予 APP 推送功能权限
用户对 APP 的推送权限进行了手动关闭
信号差、网络波动导致推送明显延迟或丢失
手机系统偶尔出现的 bug 导致推送接收失败
手机系统提供商的推送服务器问题
其他未知原因
解决问题三部曲:
第一步:删除 APP,重新下载安装后打开,在询问是否允许授予推送权限时,点击“允许” ,然后进行推送测试!
第二步:若第一步未能奏效,请重启手机,然后进行推送测试!
第三步:说出来你可能不信,如果第二步仍未奏效,请删除 APP 后重启手机,重启后下载新的 APP,打开并允许接收推送,然后进行推送测试!
除此之外根据推送的原理,如果不在厂商推送的机型,是极有可能收不到的。
解决的办法:
1、社会工程学。引导客户设置通知权限,开启白名单。可以提高到达率,主要机制是让应用不死那么快,第三方(如小米)可以活着接受到推送。
Android 可以参考云助手的推送设置方式:https://tenants.fdccloud.com/wzsversion/pub-view/wzshelper-for-phone-list
iOS记得给权限:
2、钞能力。如果是强时效性的业务,建议增加短信、电话等通知。
3、努力把自己变成强势的一方,比如每天都亿级活跃用户。
其他的问题:
特殊场景:如网络电话等,可以和厂商谈合作,但都有极高的门槛。
其他的需求欢迎咨询移动超级app一组。
最后欢迎使用移动appcloud提供的mpush插件和对各厂商封装的PHP-SDK
PHP-SDK:https://packagist.org/packages/yunchuang/push
mpush文档地址:https://appcloud-static.mypaas.com.cn/plugin/readme/mpush/1.2.4/index.html