移动终端 Android、iOS、Windows Phone 中的推送通知服务

有人的地方就有江湖,那么有智能手机的地方应该就会有推送通知。

推送并不是什么新技术,它在 PC 互联网时代就已经很流行了,最早被应用于 Email 中。只是随着进入移动互联网时代,推送技术显得更加重要。因为在智能手机中,推送通知从某种程度上,可以取代使用多年的短信,它可以展现更多形式的内容,而且用户比任何时候都渴望即时获取到新信息。

我们先来看一下,在使用推送通知技术以前,当服务器有新消息时,如何与手机客户端进行通信:

  • 轮询(Pull)方式:应用程序应当阶段性地与服务器进行连接并查询是否有新的消息,开发者必须自己实现与服务器之间的通信,如消息排队等。而且,还需要考虑轮询的频率,如果太慢可能导致某些消息延迟,如果太快,则会大量消耗网络流量和电池电量。

  • SMS(Push)方式:在 Android 平台上,应用程序可以通过拦截 SMS 消息并解析消息内容来了解服务器的意图,并获取其显示内容进行处理,这是一个很不错的想法,大概三四年前见过采用这种方案的应用,现在几乎没有了。这种方案的好处是,可以实现完全的实时操作,但是问题是这个方案的成本相对比较高,很难找到免费的短消息发送网关,而且目前 Android 系统权限管理日益严格,并不是所有应用程序都可以读取短信,所以现在基本弃用。

  • 持久连接(Push):这个方案可以解决由轮询带来的性能问题,但是还是会消耗手机的电池。Apple 的推送服务之所以工作得很好,是因为每一台手机仅仅保持一个与服务器之间的连接,事实上 Google 的 GCM 也是这么工作的。不过这个方案也存在不足,就是我们很难在手机上实现一个可靠的服务。Android 系统允许在低内存情况下杀死系统服务,所以你的通知服务很可能随时被操作系统 kill 掉了。

  • Push Notification:通常情况下,客户端主动向服务器发出请求,服务器才会向客户端传送数据,推送通知服务(Push Notification)的出现改变了这一状况,其思想是将客户端主动请求信息改变为服务器主动发送信息。服务器发送一批数据,客户端显示这些数据,同时保证与服务器的连接。当服务器需要再次发送一批数据时,客户端显示数据并保持连接。以后,服务器仍然可以发送批量数据,客户端继续显示数据,依次类推。Android、iOS、Windows Phone 平台上都有自己的推送服务,其中 Android 平台上还出现了第三方推送服务,其功能基本相同,只不过工作流程上略有差异。

Android 推送通知服务 GCM

Android Cloud to Device Messaging (C2DM) 是作为 Android 2.2 系统的一部分发布的,C2DM 允许第三方开发者开发相关应用来推送少量数据信息(1024 字节)到用户的手机上,它允许我们使用多种 Google 开发工具来创建一种简单但是相当实用的应用类型,用户可以使用该类型的应用把各种各样的信息从他们的服务端直接推送到手机上,不过,谷歌官方已经于 2012 年 6 月 26 日正式弃用,取而代之的是新版的 Google Cloud Messaging for Android (GCM) 服务,这意味着 C2DM 已经停止接受新用户和配额请求,也不会有新的特性被加入到 C2DM 中,然而,使用 C2DM 的应用当然会继续工作,现有的 C2DM 开发者都被鼓励迁移到新的 GCM 上,同时,开发者在开发新的应用的时候必须要使用 GCM。

Google Cloud Messaging for Android (GCM) 允许你从服务器发送数据到安卓设备中,同时也可以利用这个连接来接收安卓设备发过来的数据。GCM 服务处理各方面的消息队列,并将其传递到运行安卓应用程序的目标设备上。无论发送的消息多么大 GCM 都是完全免费的,并且没有配额的限制。GCM 消息应该是一个轻量级的消息,提醒应用程序需要在服务器上获取新的数据(例如:“新邮件”提醒可以提示应用程序去服务器上同步邮件),或者它也可以包含不超过 4KB 的有效载荷数据(这样,即时通讯类的应用程序就可以直接来传递消息)。

下面是 GCM 服务的一些特性:

  • 它允许第三方应用程序服务器向安卓应用程序发送消息。
  • 使用 GCM 云连接服务器,你可以接受用户设备上传过来的消息。
  • 安卓设备上的应用程序不需要保持运行来接收消息,当消息到达时,只要应用程序建立了适当的广播接收机制和权限,系统就会通过内部广播通知来唤醒应用程序。
  • 它并没有提供任何内置的用户界面或处理数据的机制,GCM 只是简单的将接收到的原始数据直接传递给应用程序,应用程序对接收到的数据有着完全控制权限。例如,应用程序会发送一条通知、显示一个自定义的用户界面,或者在后台同步数据。
  • 它需要在设备上运行安卓 2.2 或者更高的版本并且安装有谷歌应用商店,或者运行带有谷歌 API 的安卓 2.2 的模拟器。然而你可以不受限制的通过谷歌应用商店来部署你的应用程序。
  • 它需要一个已经存在的谷歌服务连接,对于安卓 3.0 之前的设备,这需要用户在移动设备中登录他们的谷歌账户,对于安卓 4.0.4 或更高版本,谷歌账户并不是必须的。

工作原理和流程

一个 GCM 的实现包括了谷歌提供的连接服务器,与连接服务器交互的第三方应用程序服务器,和在安卓设备上运行的启用了 GCM 的客户端应用程序。

  • (1)谷歌提供的 GCM 连接服务器从第三方应用程序服务器上获取消息,然后将消息发送到运行在设备上的启用了 GCM 的安卓应用程序(客户端应用)。截至目前,谷歌为 HTTPXMPP 提供连接服务器。
  • (2)第三方应用程序服务器是你和你所选择的 GCM 连接服务器实施工作的一个组件,应用程序服务器将消息发送到 GCM 连接服务器,连接服务器将这些消息加入队列名存储,然后当设备在线的时候将其发送给设备。更多信息请参见实现 GCM 服务器
  • (3)客户端应用程序是运行在设备上的启用了 GCM 的的应用程序。为了接收 GCM 消息,应用程序必须和 GCM 注册,并获取到注册 ID,如果你使用 XMPP(CCS) 连接服务器,则客户端可以使用上传数据流来向服务端发送消息。关于实现客户端应用的更多信息,请参见实现 GCM 客户端

第三方推送

由于 GFW 的原因,谷歌的 GCM 服务在国内基本是无法使用,所以现在国内安卓应用开发商一般基于 XMPP 协议或者 MQTT 协议自己实现持久连接通信。当然国内也有类似很多成熟的提供推送服务的厂商,如:腾讯信鸽极光推送等。

iOS 推送通知服务 APNS

APNS(Apple Push Notification Services)是苹果公司官方提供的消息推送服务,也是 iOS 上唯一的消息推送服务,任何想要使用推送服务的 APP 都必须使用此项服务。每台设备要与推送服务建立起加密认证的 IP 连接并通过这个持续的连接来接收通知。如果通知到达的时候应用程序没有在运行,则设备会提示用户该应用程序有数据等待处理。

应用开发者(供应商)在他们的服务器软件中生成通知消息,供应商通过一个持续的安全的通道与 APNS 进行连接并同时监视要发送到客户端程序中的数据,当新的数据到达时,提供者就会准备好并通过上面的通道将通知发送到 APNS,这会将通知推送到目标设备中。

苹果推送通知服务从一个指定的供应商到一个指定的设备传输通知,一条通知是一个由两个主要部分组成的短消息:设备令牌和有效载荷。设备令牌是一种类似于电话号码的东西,它包含了能够使 APNS 定位到安装了客户端程序的设备上。APNS 也使用设备令牌来验证一条通知的路由。有效载荷是一条 JSON 定义的属性列表,指定了设备上的应用程序如何来提醒用户。

推送通知的数据流是单向的,供应商(Provider)为客户端应用程序创建一条包含了设备令牌的通知和有效载荷,供应商将通知发送到 APNS,反过来 APNS 又将通知推送到设备中。当供应商验证自身身份到 APNS 之后 他会将自己的主题发送到 APNS 服务器,这个主题标识了它将会向哪个应用程序提供数据。主题目前也是绑定目标应用程序的标识符。

下图表示了一条推送通知从供应商到客户端应用程序的路径。

上图是一个大大简化了的 APNS 虚拟网络,实际情况中,APNS 的设备端和供应商端都有许多连接点。在供应商那一侧的连接点叫做网关。有许多供应商,每个供应商都通过网关和 APNS 维持一个或多个持续的安全连接,这些供应商通过 APNS 向安装了他们应用程序的设备上推送通知,下图是一个比较接近实际的描述。

另外,每次推送的回执服务向供应商提供关于消息无法被成功送达的消息,例如因为目标应用程序已经从设备上卸载。更多信息,请参见“回执服务”。

工作流程

在发送消息到客户端设备接收到消息的过程中,始终伴随这一个令牌的传送(device token)。要想使用 APNS 提供消息服务,应用程序需要先向 iOS 注册需要提供的一个必要的信息就是与当前设备有关的 device token,iOS 在接收到 device token 后,会向 APNS 查询这个 device token 是否在 APNS 上注册了,如果已经注册,APNS 会直接向应用程序返回这个 device token。应用程序获得这个 device token 后,表示 APNS 已经允许向自己推送消息了,接着还需要将该 device token 发送给推送服务器(Provider)。到这里应用程序已经成功将自己注册到 APNS 中了。现在就可以通过 Provider 产生要推送的消息,然后 Provider 会将消息发送给 APNS 服务器,最后 APNS 服务器会直接向应用程序发送消息。这个过程比较复杂,不过看一下图的描述就会对这一过程更加了解了。每一个流程描述前面的数字表示发送的时间先后顺序。

Windows Phone 推送通知服务 MPNS

推送通知是 Windows Phone 上的内置特性,开发者可以利用 Windows Phone 的消息推送服务来实现网络服务器向手机客户端推送一些通知或者消息。Microsoft Push Notification Service 是 Windows Phone 上的一个异步的推送服务,向第三方应用程序开发者提供了一条高效能的从云端向 Windows Phone 应用程序传递数据的通道。

Windows Phone 的推送通知有3种不同的类型,分别是原生通知(Raw Notification)、Toast通知(Toast Notification)和磁贴通知(Tile Notification)。这三种通知的表现形式和消息传送的格式各不相同,可以根据应用的具体情况来选择需要的通知形式。

下图展示了推送消息是如何发送的。

  • (1)你的应用程序向推送客户端服务发送一个推送 URI 的请求。
  • (2)推送客户端服务与 Microsoft Push Notification Service 交互,然后 MPNS 向推送客户端服务返回一条通知 URI。
  • (3)推送客户端服务将通知 URI 返回给你的应用程序。
  • (4)你的应用程序将推送 URI 发送到你的云服务中。
  • (5)当你的云服务需要向你的应用程序发送消息的时候,他使用这个通知 URI 向 MPNS 发送一条通知。
  • (6)MPNS 将这条推送通知发送到你的应用程序。

根据推送通知的格式以及附加的有效载荷,该信息以原始数据的形式被发送给应用程序,然后应用程序的图标会被更新,或者显示 Toast 通知。在发送完推送通知之后, MPNS 给你的云服务会返回一个回执码,表示该消息已经被 MPNS 接收并将在何时的时机发送给目标设备。尽管 MPNS 并没有提供端到端的服务来确认你的推送通知已经从你的云服务发送到了你的手机中,如果该条消息不能被发送到设备中,MPNS 会向你的云服务中返回一条错误码。更多关于回执和错误码的信息,请参见 Windows Phone 推送通知服务的响应代码.aspx)。在 MPNS 表明消息无法被传递的时候,你的服务应该在需要的情况下重新提交这条消息。

Reference