在 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 实现开放源码,敬请期待。

APNs 推送原理及问题的更多相关文章

  1. APNS推送原理详解

    推送是解决轮询所造成的流量消耗和电量消耗的一个比较好的解决方案,在Android上,虽然Google提供了GCM(之前为C2DM),但在国内基本等于没用,各大Android应用基本都自己架设推送Ser ...

  2. python3 三行代码基于HTTP2完美实现APNS推送【详解】

    第一次做苹果APNS(Apple Push Notification service)推送,关于APNS推送原理以及证书的获取方式网上已经有许多资料,在此不做过多赘述,需要注意的是证书分为测试证书和正 ...

  3. iOS远程推送原理及实现过程

    ➠更多技术干货请戳:听云博客 推送通知,是现在的应用必不可少的功能.那么在 iOS 中,我们是如何实现远程推送的呢?iOS 的远程推送原理又是什么呢?在做 iOS 远程推送时,我们会遇到各种各样的问题 ...

  4. IOS - 消息推送原理和实现

    一.消息推送原理: 在实现消息推送之前先提及几个于推送相关概念,如下图1-1: 1.Provider:就是为指定IOS设备应用程序提供Push的服务器,(如果IOS设备的应用程序是客户端的话,那么Pr ...

  5. iOS 消息推送原理及实现Demo

    一.消息推送原理: 在实现消息推送之前先提及几个于推送相关概念,如下图1-1: 1.Provider:就是为指定IOS设备应用程序提供Push的服务器,(如果IOS设备的应用程序是客户端的话,那么Pr ...

  6. [iOS]iPhone推送原理

    推送原理,先上图 说一下原理吧, 由App向iOS设备发送一个注册通知 iOS向APNs远程推送服务器发送App的Bundle Id和设备的UDID APNs根据设备的UDID和App的Bundle ...

  7. iOS 消息推送原理

    一.消息推送原理: 在实现消息推送之前先提及几个于推送相关概念,如下图: 1. Provider:就是为指定IOS设备应用程序提供Push的服务器,(如果IOS设备的应用程序是客户端的话,那么Prov ...

  8. iOS开发消息推送原理

    转载自:http://www.cnblogs.com/cdts_change/p/3240893.html 一.消息推送原理: 在实现消息推送之前先提及几个于推送相关概念,如下图1-1: 1.Prov ...

  9. iOS远程消息推送原理

    1. 什么是远程消息推送? APNs:Apple Push Notification server 苹果推送通知服务苹果的APNs允许设备和苹果的推送通知服务器保持连接,支持开发者推送消息给用户设备对 ...

随机推荐

  1. 操作json数据

    删除: delete json[key] 把json字符串转成jsonObject : eval(+'('+json+')'+) 把jsonObject 转换成json字符串 :json.toJSON ...

  2. LambdaToSql 发布 兰姆达转换sql

    文档目录索引 查询.函数.分组.排序.分页 添加 Insert into 编辑 Update set 删除 Delete 生成实体 内置常用工具类库  文档完善中... 事务处理 Join 连接查询 ...

  3. AMDP + XLSX Workbench 报表开发模式

    本文介绍了我和同事通过使用AMDP + XLSX Workbench缩短报表开发周期.分离数据查询处理逻辑和前端展示工作的经验.欢迎讨论. 前言 最近接到了一套人力资源报表的开发需求,需要以EXCEL ...

  4. CDH安装系统环境准备——虚拟机网络配置

    虚拟机网络配置教程如下: 1.修改网络配置文件[root@master ~]# vi /etc/sysconfig/network-scripts/ifcfg-eth0配置IP地址.网关.掩码.DNS ...

  5. UML类图中连接线与箭头的含义(转)

    UML类图是描述类之间的关系 概念 类(Class):使用三层矩形框表示. 第一层显示类的名称,如果是抽象类,则就用斜体显示. 第二层是字段和属性. 第三层是类的方法. 注意前面的符号,'+'表示pu ...

  6. 使用IntelliJ IDEA的小技巧快乐编程(2)

    前言 本篇介绍的技巧为IntelliJ IDEA中自动代码生成相关的技巧,合理的使用这些技巧将大大提高的你的编码效率 :) Trick 6. 使用模板代码 idea默认的提供了许多模板代码,你可以使用 ...

  7. Lintcode395 Coins in a Line II solution 题解

    [题目描述] There are n coins with different value in a line. Two players take turns to take one or two c ...

  8. 微软云消息队列 Azure service bus queue

    前言 第一次使用消息队列,遇到了一些问题:同一个消息有多次出列.是一个消息只入列一次,还是多次?还是因为出列问题,出列了多次? Microsoft Azure service bus queue Az ...

  9. 食物链-HZUN寒假集训

    食物链 总时间限制: 1000ms 内存限制: 65536kB 描述 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动 ...

  10. Java获取当日的起始时间,结束时间,现在时间,是否在时间段中。

    当日的起始时间 public static Date getTodayStartTime() { Calendar todayStart = Calendar.getInstance(); today ...