蛋疼的Apple IOS Push通知协议

简介

Apple Push通知机制其实很简单,就是Apple的APNs服务器做为中间人,把消息推送到对应的设备上。

一张来自Apple文档的图:

当然,示意图看起来简单,但是还有一些实际的问题。

比如,如何区分Provicer的?如何区分设备的?

简单而言,是这样的:

  • 每个应用都有一个自己的证书(certificate),开发者可以从苹果那里获得;
  • 应用可以到APNs服务器上注册(register),然后得到一个device_token,开发者要自己保存好,推送时就要用这个来区分不同的设备。
  • 注意,token并不是设备唯一标识码。token是可以改变的,因此APNs提供了一个feedback服务,开发者可以得到失效的token。
  • 对于每个设备只存储最后的一条push,所以如果连续发很多条push,设备没有及时接收的话,后面的push会覆盖前面的。
  • Provider和APNs服务器,APNs服务器和用户设备之间的通迅都是SSL/TLS协议的。这点要比国内的推送服务商要做的好,国内的推送服务都是http接口的,完全没有加密。
  • Push都是对于设备而言的。所以敏感信息不要通过push来传递。
  • Push是尽量送达的,Push消息可能会丢失,所以不要用Push来传递可靠数据。

Apple Push的协议蛋疼之处

上面只是有一些要注意的小地方,下面来说下真正蛋疼的东西:Apple Push的协议。

首先,明显的是设计不良:

协议里的command,现在实际上也用来表示Version。

比如command = 0, 1, 2就分别表示发送消息的三个版本。

更蛋疼的是前面0,1两个版本现在的文档都找不到了。这个让维护老代码的人情何以堪?想调试下bug,结果发现官方文档都消失了,那得多蛋疼。

Apple的文档里只说到:


Field name


Length


Discussion


Command


1 byte


Populate with the number 2.

可能在你看这篇文章的时候,变成了“Populate with the number 3”了。。

正常人看到这里只会觉得一头雾水,为什么这个command是2?怎么想得到这个Command居然是和版本相关的。。我是从别的一些实现代码里才知道有三个版本的。

协议格式混乱

比如这个feedback的格式:

deviceToken就是固定好了是32字节的,前面还要加一个Token length。

有人可能说,这是考虑了以后token大于32字节的。那干脆应该为feedback的回应包加上版本号。

发送者可以批量发送消息,但是只有出错的时候才会返回出错消息的ID。

这个乍看起来,没什么问题。但是当你想要实现一个Push客户端的时候,就知道蛋疼之处了:

发送者连续发了1,2,3,4 ... 100 条消息,已经写到socket里去了,这里APNs服务器回应说第57条消息失败了。

那发送者得从第58条开始,重新再发。那发送者得把前面已经发送出去了的消息缓存起来!

好的,缓存一下也没关系,那么到底缓存多少个消息呢?1024个?2048个?天知道。

要是发送者的网速快,一下子把4096个消息都发出去了呢?那怎么办?

好吧,也许你会说4096个消息体比较大小,Apple的服务器的TCP socket缓冲区都满了,你发不了这么多的消息。

我只是想发个Push消息而已,难道还要推算APNs服务器的socket缓冲区的大小?要是它的网络框架也做了缓冲呢?要是发送者的网络框架也做了缓冲呢?

是不是每次发送时,都要等待数据全都写到socket里去了?

开发者测试用的沙箱服务器是个摆设

文档上写了在开发环境可以用这个域名,gateway.sandbox.push.apple.com。但是坑爹的是,这个域名实际上是个摆设,你可以建立SSL连接,也可以正常发送消息。

但是你的设备却是收不到消息的。要是在实现自己的客户端时,用这个来测试,就蛋疼了,一次次检查自己的代码,看是否有问题,最终却发现是对方的服务器有问题。。

只有程序员才能明白这种蛋疼的心情。

不支持分组发送

现在的国内流行的推送服务,如百度推送等,都支持分组的配置,这样大大节省了带宽,提离了发送效率。

可能还有一些蛋疼的地方,忘记了,下篇blog说下一些实现自己的客户端要注意的事项及一个Java的实现ZPush。

参考:

https://developer.apple.com/library/ios/technotes/tn2265/_index.html   这个文档很值得参考,说到了一些实现的要点。

http://support.apple.com/kb/HT3576?viewlocale=zh_CN&locale=zh_CN

https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/ApplePushService.html#//apple_ref/doc/uid/TP40008194-CH100-SW12

https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/CommunicatingWIthAPS.html

https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/CommunicatingWIthAPS.html#//apple_ref/doc/uid/TP40008194-CH101-SW1

时间: 2024-11-18 21:57:36

蛋疼的Apple IOS Push通知协议的相关文章

iOS - Push 通知推送

1.UserNotifications 通知是 App 用来和用户交流的一种方式,特别是当 App 并没有在前台运行的时候.通知,正如它的名称所强调的,被用作向用户'通知'一个事件,或者仅仅向用户提示一条重要信息.总而言之,通知在提示类型的 App 当中非常有用,甚至在一些别的类型的 App 当中也是如此.比如,当用户进入一个指定区域(这是 iOS8 的新特性),一个下载任务完成,或者当朋友给你发送一条信息的时候,一条通知就可以被显示出来.无论如何,通知的目的就是获得用户的关注,然后他们就能处理

iOS - Notification 通知

1.Notification 通知中心实际上是在程序内部提供了消息广播的一种机制,它允许我们在低程度耦合的情况下,满足控制器与一个任意的对象进行通信的目的.每一个 iOS 程序(即每一个进程)都有一个自己的通知中心,即 NSNotificationCenter 对象,该对象采用单例设计模式,可以通过类方法 defaultCenter 获得当前进程唯一的通知中心对象.一个 NSNotificationCenter 可以有许多的通知消息 NSNotification,对于每一个 NSNotifica

IOS中通知中心(NSNotificationCenter)的使用总结

IOS中通知中心NSNotificationCenter应用总结 一.了解几个相关的类 1.NSNotification 这个类可以理解为一个消息对象,其中有三个成员变量. 这个成员变量是这个消息对象的唯一标识,用于辨别消息对象. @property (readonly, copy) NSString *name; 这个成员变量定义一个对象,可以理解为针对某一个对象的消息. @property (readonly, retain) id object; 这个成员变量是一个字典,可以用其来进行传值

ios push过去的界面,为什么会没有标签栏?

问题描述 ios push过去的界面,为什么会没有标签栏? 点击某个tableView表格,跳转到下一个页面的时候,标签栏就没了,这是为什么? 解决方案 DCAddFriendsViewController *addFriendVC = [[DCAddFriendsViewController alloc] init]; addFriendVC.hidesBottomBarWhenPushed = YES; //push 之前,加这么一句话就不会有了,反之,你加了吗? [self.navigat

ios开发-iOS使用xmpp协议实现即时 语音通话,视频通话

问题描述 iOS使用xmpp协议实现即时 语音通话,视频通话 本人用该协议做了 语音图片和文字发送,但是视频和语音通化没有资料,没有思路.不知道从哪里下手.有人做过 或者了解的能告诉一下吗? 解决方案 (iOS)基于XMPP协议的简单IM实现

运行缓慢 - Apple iOS 4引起iPhone用户抱怨

http://www.aliyun.com/zixun/aggregation/5541.html">Apple iOS 4系统的发布已经面临一些iPhone用户的反对.该系统适用于iPhone4,iPhone 3G,iPhone 3GS以及2009年后的iPod touch设备,为iPhone 4和3GS添加了多任务功能,并宣称有100项新特性.另外还有文件夹,电子书籍,蓝牙键盘等.然而,Twitter用户很快批评了这种 更新.有人说安装iOS4之后iPhone 运行变得不可思议的慢.还

绿盟科技网络安全威胁周报2017.13 关注Apple iOS WI-FI远程代码执行漏洞CVE-2017-6975

绿盟科技发布了本周安全通告,周报编号NSFOCUS-17-13,绿盟科技漏洞库本周新增34条,其中高危4条.本次周报建议大家关注 Apple iOS WI-FI远程代码执行漏洞 .目前厂商已经进行了修复,强烈建议用户检查自己的系统是否为受影响版本,如果是,请尽快升级. 焦点漏洞 Apple iOS WI-FI远程代码执行漏洞 NSFOCUS ID 36325 CVE ID CVE-2017-6975 受影响版本 iOS Version <= 10.3 漏洞点评 博通(Broadcom)WI-FI

ios push apns iphone-如何获取ios设备当前处于离线还是在线(活跃)状态?

问题描述 如何获取ios设备当前处于离线还是在线(活跃)状态? ios推送消息的服务端实现,如何判断目标设备离线从而不往设备推送消息,因苹果推送 服务器APNS只保留最新一条离线通知,所以可能造成之前的离线消息被覆盖,这样就会有 消息的丢弃情况,应该如何来避免解决这个问题,请有经验的小伙伴帮忙解答一下呢? 解决方案 不管APNS帮你管理几条,你的业务服务器和端之间肯定要有一种消息同步机制,保证消息的可靠可达性,一般做法就是每一条消息都有id,这样端连接服务器的时候即可以根据时间戳+id来同步未读

iOS中 通知中心Text (实例)

版权声明:本文为博主原创文章,未经博主允许不得转载. [objc] view plain copy    指定根视图 [objc] view plain copy self.window.rootViewController = [RootViewController new];   方法实现: [objc] view plain copy #import "RootViewController.h"   #define kScreenHeight [UIScreen mainScre