Files
knowledge-kit/Chapter7 - Geek Talk/7.7.md
2020-02-25 17:46:51 +08:00

60 lines
6.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 浅谈iOS和Android后台实时消息推送的原理和区别
> 前言 iOS和Android上的实时消息推送差异很大往小了说是技术实现的差异往大了说是系统实现理念的不同。实时消息推送在移动端互联网时代很平常也很重要它的存在让智能终端真正成为全时信息传播的工具。本文将从原理上谈谈两个平台上实时消息推送的区别。
* 简要对比
* iOS 系统的推送APNS即 Apple Push Notification Service依托一个或几个系统常驻进程运作是全局的接管所有应用的消息推送所以可看作是独立于应用之外而且是设备和苹果服务器之间的通讯而非应用的提供商服务器。你的例子里面腾讯 QQ 的服务器Provider会给苹果公司对应的服务器APNs发出通知然后再中转传送到你的设备Devices之上。当你接收到通知打开应用才开始从腾讯服务器接收数据跟你之前看到通知里内容一样但却是经由两个不同的通道而来。
* Android就不同更像是传统桌面电脑系统做法。每个需要后台推送的应用有各自的单独后台进程才能和各自的服务器通讯交换数据。另外其实 Android 也有类似 APNS 的 GCMGoogle Cloud Message属于开发者可选非强制。
* 技术原理
* 首先讲解下服务器如何先找到设备、再找到app的问题。
* 每一个设备都有一个自己的设备号而设备中的app又都有一个唯一的包名。所以服务器只需要找到设备号与包名就可以定位到某个设备的某个应用而这设备号与包名会一起构成一个标识符叫做device\_token因此问题就简化为把device\_token与消息内容等信息交给服务器服务器把内容发到唯一的device\_token上。这就好像你在上海要通过顺丰寄送一个快件儿给某某小区的某某房间那么快件儿首先会邮递到顺丰公司在北京的总站点之后再根据小区的地址投递/路由到某某房间,这样一个寄件过程就算完成了。
* iOS 实时消息推送
iOS的推送是通过苹果自己的APNs服务进行的用户需要将device\_token以及消息内容等推送信息交给APNs服务器剩下的均由苹果自己来完成。iOS应用的推送大部分情况下都要依赖苹果生态提供的APNsApple Push Notification Service服务。
https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/db29e6a729147172d199cde6e2cf3682_hd.png
![](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/db29e6a729147172d199cde6e2cf3682_hd.png)
首先作为设备标识的device-token是由APNs颁发的App开发者或者第三方推送平台\(图中的Provider\)做的工作是收集这个device-tokenAPNs的推送是要求基于APNs颁发的device-token来推送的。只有正确的device-token会被APNs接受如果是一个错误的、或者无效的device-token\(比如App已经卸载了\)APNs就不会接受。
![](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/442e4085cf4b8f62c7ad359343c5f155_hd.png)
接着开发者使用第三方推送平台图中的Provider在将推送内容与范围选定之后进行推送第三方推送平台将信息提交给APNs剩下的操作全部都由APNs来进行完成整个过程第三方推送平台就不能控制了。但是如果提供的device\_token是失效的app被卸载、系统版本升级导致device\_token变化等情况那么推送过程就会被中断频繁的断线重连甚至会被APNs认为是一直DoS攻击。[详情可以参考为什么苹果的推送,两次推送之间间隔比较久的话,第二次推送会很慢?](http://www.baidu.com)
* Android 实时消息推送
Android平台在不使用GCM的情况下就需要将自己的服务器或是第三方推送服务提供商的服务器与设备建立一条长连接通过长连接进行推送。但是不建议自己设置服务器实现推送功能一是因为成本太高开发成本、维护成本自己搭建的服务器无论是稳定性还是速度上都比不了第三方推送服务提供商的效果。另一个是因为自己的数据量较小使用第三方推送服务提供商可以用他们的维度进行推送实现精准推送。友盟推送就是做的比较好的可以根据用户分群、地区、语言等多维度进行推送最大程度减少对于用户的干扰仅把消息推送给相关用户。![](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/224420fhxsp8e00v0s0b0s.png)
* 开发者通过第三方推送服务提供商将信息直接下发给需要的设备第三方推送服务提供商与设备建立一条长连接通道并且将消息路由到APP中图中的设备1与设备2对于像设备3这种无网络连接或是没有成功建立长连接通道的设备会在设备3连网且推送消息没有过期的情况下自动收到由第三方推送服务提供商推送过来的消息保证消息不会丢失。
* ## 实现上的差异所带来的直观感受
* ### iOS的实时消息推送
iOS 在系统级别有一个推送服务程序使用 5223 端口。使用这个端口的协议源于 Jabber 后来发展为 XMPP ,被用于 Gtalk 等 IM 软件中。
![](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/224819kyaynn1zzoyoulzn.jpg.png)
所以 iOS 的推送可以不严谨的理解为:
* 苹果服务器朝手机后台挂的一个 IM 服务程序发送的消息。
* 然后,系统根据该 IM 消息识别告诉哪个 Apps 具体发生了什么事
* 然后,系统分别通知这些 Apps 。
带来的好处是不会出现杀后台这种脑残事。(不用大量 Apps / Apps 的服务为了推送挂后台)。也不会出现 Apps 被杀就收不到推送这种脑残事(早一点的新浪微博 Android 版仍然如此)。
* Android的实时消息推送
Apps 挂后台一直是 Android 引以为豪的特性(虽然我真的不知道是好处多还是坏处多。。),大家挂后台等待推送就成为技术选择。当然, Google 事后也提供类似苹果的推送方式了。倒也谈不上抄袭,毕竟苹果的整个技术实现也没有什么特别创新之处。
用户的电池? Apps 的开发者不会站在系统层面考虑的。他会假设其他 Apps 没有那么“不自觉”。而 Google 不强制的结果就是:没人真正为用户的电池负责。
但是, Google 的方案也并非全是悲剧:也因为整个技术方案非强制, Android 的 Apps 在接收到推送后的表现更为灵活。像 Line 的 Android 版本可以在推送通知的 Popup 上直接回复, iOS 就需要越狱才能做到了。