批量推送Apple推送通知

我有一个应用程序,包括定期向〜1M用户发送Apple推送通知。 这样做的设置已经build立并testing了less量的通知。 由于我无法testing这种规模的发送方式,因此我很有兴趣知道发送批量推送通知是否有任何问题。 我有Python编写的脚本,打开到推送服务器的单个连接,并通过该连接发送所有通知。 苹果build议尽可能保持开放。 但是我也看到连接终止,你需要重新build立连接。

总而言之,成功发送不被承认是令人不安的,只有错误的发送被标记。 从程序员的angular度,而不是简单地检查一件事情“如果(成功)”,你现在需要注意许多可能出错的事情。

我的问题是:你需要警惕哪些典型的错误,以确保你的消息不会悄无声息地消失? 连接closures很容易。 有其他人吗?

我完全同意你的看法,这个API是非常令人沮丧的,如果他们发送了每个通知的响应,那实现起来就容易多了。

这就是说,苹果公司说你应该做什么(来自技术说明 ):

推送通知吞吐量和错误检查

使用APN没有上限或批量限制。 iOS 6.1新闻稿指出,APN自成立以来已经发送了4万多个推送通知。 在WWDC 2012上宣布,APN每天发送70亿个通知。

如果您看到吞吐量低于每秒9,000个通知,则您的服务器可能会受益于改进的error handling逻辑。

以下是使用增强二进制界面时如何检查错误的方法。 继续写,直到写入失败。 如果stream已准备好再次写入,请重新发送通知并继续。 如果stream尚未准备好写入,请查看stream是否可用于读取。

如果是,请阅读stream中可用的所有内容。 如果返回零字节,则由于诸如无效的命令字节或其他parsing错误之类的错误而导致连接closures。 如果返回六个字节,那么这是一个错误响应,您可以检查响应代码和导致错误的通知的ID。 您需要再次发送所有通知。

一旦所有的东西都发完了,最后一个检查是否有错误。

由于正常的延迟,丢弃的连接可能需要一段时间才能从APN返回到服务器。 在写入失败之前,可能发送超过500个通知,因为连接被丢弃。 大约1,700个通知写入可能会因为pipe道已满而失败,所以只要stream再次准备好写入就重试。

现在,这里的权衡变得有趣。 您可以在每次写入后检查错误响应,然后马上发现错误。 但是这会导致发送一批通知所花的时间大大增加。

设备令牌应该几乎都是有效的,如果您已经正确捕获它们并且将它们发送到正确的环境。 所以这是有道理的,优化假设失败将是罕见的。 如果在检查错误响应之前等待写入失败或批量完成,即使计算再次发送已丢弃的通知的时间,也可以获得更好的性能。

这些都不是特定于APN的,它适用于大多数套接字级编程。

如果您select的开发工具支持multithreading或进程间通信,则可以让线程或进程始终等待错误响应,并让主发送线程或进程知道何时应放弃并重试。

我们只是想用第一人称的angular度来报道,因为我们每天都会发送数百万个APNS通知。

不幸的是参考文献@Eran引用了关于苹果如何pipe理APNS套接字的最佳资源。 对于低销量来说,这样做还是不错的,但苹果公司的文档总体上偏向于那些偶然的,小批量的开发者。 一旦你达到规模,你会看到很多无证的行为。

该文档中关于asynchronous检测错误的部分对于高吞吐量至关重要。 如果你坚持要阻止每次发送错误,那么你需要大量的并行工作来保持吞吐量。 然而,推荐的方式是发送速度尽可能快,只要发生错误,修复和重放。

该职位我不同意的部分是:

设备令牌应该几乎都是有效的, 如果您已经正确捕获它们并且将它们发送到正确的环境。 所以这是有道理的,优化假设失败将是罕见的

预言这样一个巨大的“IF”的build议似乎是非常具有误导性的。 我几乎可以保证大多数开发人员不会捕获令牌,并“正确”处理100%的苹果反馈服务。 即使是这样,系统本身也是有损的,所以漂移将会发生。

我们看到一个非零数量的错误#8响应(无效的设备令牌),我认为这是根源电话,客户端错误或用户故意欺骗他们的令牌给我们。 过去我们也看到了一些错误#7(无效载荷大小),我们追踪到了开发人员在我们末端添加的不正确的编码消息。 那当然是我们的错,但这就是我的观点 – 说“优化假设失败将是罕见的”是发送给学习开发者的错误信息。 我想说的是:

假设错误会发生。

希望它们不经常发生,但是防守编码,以防他们不这样做。

如果优化假设错误很less,那么只要APNS服务closures,您发送的每条消息都会返回错误#10,则可能会使基础架构处于风险之中。

试图找出如何正确回应错误时,麻烦来了。 关于如何正确处理和从不同的错误中恢复的文档是不明确的或缺less的。 这显然是读者的一个练习。