APNs 推送原理及问题

freerocker 2013-05-17 02:52:34
在 iOS 平台上,大部分应用是不允许在后台运行并连接网络的。在应用没有被运行的时候,只能通过 Apple Push Notification Service (APNs) 把数据发送到终端用户。对于互联网应用,正确高效的使用 APNs 显然非常重要。

JPush 为 iOS、Android 平台提供了一个统一推送消息的平台,而对 APNs 接口的封装管理是其中非常重要的一部分。本文分享一下 JPush 团队在使用 APNs 过程中碰到的问题以及我们的解决办法,以帮助应用开发者更好的理解 APNs。

Apple 为应用开发者提供了一个 APNs 推送接口,称为 binary interface。

Binary Interface V1

最初版本的 binary interface 协议如下图,这里我们称之为 v1。

Binary Interface V1



v1 协议有几个问题:

消息是否发送成功没有明确的反馈;
如果一个消息发送失败,比如因为 deviceToken 不合法,APNs 会在大约 500ms 后断掉链接,在断链前发送的消息也会发送失败;
经我们验证,feedback service 只有报告应用被卸载后,造成 deviceToken 失效的错误。而不会报告 deviceToken 不合法这种类型的推送错误。
也就是说如果我们给一批用户发消息,只要有一个 deviceToken 不合法,将会有可能造成若干个用户收不到消息。并且没办法确认哪些 deviceToken 不合法,哪些 deviceToken 需要被重发。这应该是 APNs 丢消息的一个重要的原因。

Binary Interface V2

经过开发者不断的向 Apple 反馈这个问题,Apple 终于推出了一个新版本的 binary interface,称为 enhanced binary interface,我们称这为 v2。

Binary Interface V2



我们发现,在 v1 的基础上增加了两个字段:

Identifier —— 一个任意的值,用于一条消息的识别。如果发送出现问题,错误应答里会把 Identifier 带回来。

Expiry —— 离线消息超时的时间,如果为0或者小于0,APNs 不会保存这条消息。

和 v1 一样,如果消息发送没有问题,APNs 不会有任何返回。和 v1 不同,并且很重要的改进是,如果发送出现错误,v2 会在断链之前返回一个错误应答,带上发消息时的 Identifier 和一个错误码。

error-response packet



根据这个错误应答,我们有机会找到是哪条消息发送出错,并确定哪些消息需要被重发。

JPush 的解决办法

为了确保每一位用户都能正确的收到消息,JPush 目前已经放弃 binary interface v1,完全采用 binary interface v2。(在我写这篇文章时,发现 Apple 已经把文档中对 binary interface v1 的描述移除,看来 Apple 也已经放弃 v1)

在系统设计上,我们为每一个 APNs 链接维护 一个已发送列表,按发送的先后顺序排序。如果收到发送错误应答,根据返回的 Identifier 找到出错的消息,从该消息的下一条重新开始发送。

发送队列



总结

为了持续提高 JPush 推送服务的质量,我们团队做了很多研究和尝试。APNs 管理模块我们最初用 C 语言实现了一个版本,后来觉得用 Erlang 实现可能更方便,所以又从头开始学习 Erlang 并重新用 Erlang 写了一个版本,目前使用效果良好。

在 APNs 管理系统改造的过程中,包括 JPush 的其他模块,都大量的使用了开源的模块或者系统,为了回馈开源社区,我们准备把 APNs 管理系统的 Erlang 实现开放源码,敬请期待。
...全文
1554 37 打赏 收藏 转发到动态 举报
写回复
用AI写文章
37 条回复
切换为时间正序
请发表友善的回复…
发表回复
miss_chalk 2014-03-12
  • 打赏
  • 举报
回复
看来三个很火,极光推送,百度推送,苹果推送。
bigsonn 2014-02-18
  • 打赏
  • 举报
回复
而对 APNs 接口的封装管理是其中非常重要的一部分。
segman 2014-01-22
  • 打赏
  • 举报
回复
用 Erlang 实现可能更方便
xinzhnn 2014-01-17
  • 打赏
  • 举报
回复
Expiry —— 离线消息超时的时间,如果为0或者小于0,APNs 不会保存这条消息。
blaack 2014-01-14
  • 打赏
  • 举报
回复
没办法确认哪些 deviceToken 不合法,哪些 deviceToken 需要被重发。这应该是 APNs 丢消息的一个重要的原因。
TTrunc 2014-01-09
  • 打赏
  • 举报
回复
feedback service 只有报告应用被卸载后
beacal 2014-01-02
  • 打赏
  • 举报
回复
如果一个消息发送失败,比如因为 deviceToken 不合法,APNs 会在大约 500ms 后断掉链接,在断链前发送的消息也会发送失败;
nighmi 2013-12-12
  • 打赏
  • 举报
回复
源码在哪?
immedia 2013-11-29
  • 打赏
  • 举报
回复
在应用没有被运行的时候,只能通过 Apple Push Notification Service (APNs) 把数据发送到终端用户。
biiko 2013-11-14
  • 打赏
  • 举报
回复
Expiry —— 离线消息超时的时间,如果为0或者小于0,APNs 不会保存这条消息。
kaoopu 2013-11-08
  • 打赏
  • 举报
回复
对于互联网应用,正确高效的使用 APNs 显然非常重要。
sunsengood 2013-11-05
  • 打赏
  • 举报
回复
v1的消息是否发送成功没有明确的反馈
reopen 2013-11-01
  • 打赏
  • 举报
回复
有些 deviceToken 不合法,哪些 deviceToken 需要被重发。
bakewa 2013-10-30
  • 打赏
  • 举报
回复
如果我们给一批用户发消息,只要有一个 deviceToken 不合法,将会有可能造成若干个用户收不到消息。并且没办法确认哪些 deviceToken 不合法,哪些 deviceToken 需要被重发
mastte 2013-10-28
  • 打赏
  • 举报
回复
啥时候输出源码?
alwaysall 2013-10-24
  • 打赏
  • 举报
回复
期待你们开放源码
letbo 2013-10-21
  • 打赏
  • 举报
回复
feedback service 只有报告应用被卸载后,造成 deviceToken 失效的错误。而不会报告 deviceToken 不合法这种类型的推送错误。
brucelllll 2013-10-16
  • 打赏
  • 举报
回复
在 iOS 平台上,大部分应用是不允许在后台运行并连接网络的。
bosken 2013-10-12
  • 打赏
  • 举报
回复
期待你们开放源码
jealba 2013-10-11
  • 打赏
  • 举报
回复
V2和 v1 一样,如果消息发送没有问题,APNs 不会有任何返回。和 v1 不同,并且很重要的改进是,如果发送出现错误,v2 会在断链之前返回一个错误应答,带上发消息时的 Identifier 和一个错误码。
加载更多回复(16)

790

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 其他移动相关
社区管理员
  • 移动开发其他问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧