批量发送苹果推送通知

26

我有一个涉及向大约一百万用户定期发送苹果推送通知的应用程序。已经建立并测试了小批量通知的设置。由于我无法在这样的规模下进行测试,因此我想知道在发送大量推送通知时是否有任何需要注意的事项。 我使用Python编写了脚本,打开一个与推送服务器的连接并通过该连接发送所有通知。苹果建议尽可能保持连接打开状态。但是我也发现,连接会终止,您需要重新建立它。

总的来说,令人不安的是,只有错误的发送被标记,而成功的发送没有得到确认。从程序员的角度来看,你不仅需要检查“if (success)”这一件事情,还需要关注许多可能会出错的事情。

我的问题是:为了确保您的消息不会悄悄地消失,请注意哪些典型的错误?连接关闭是一个简单的问题。还有其他的吗?


你找到发送iPhone批量推送通知的方法了吗?因为我没有找到任何方法 :/ - user2754681
如果你刚开始使用推送服务,那么可以考虑使用Urban Airship,它每月提供约100万次免费推送,但价格非常昂贵。如果你的推送量超过这个范围,那么你可以考虑使用亚马逊的SNS服务(比Urban Airship便宜几个数量级),这也是我使用的服务。 - er0
但我正在使用免费的方式发送我的推送,因此必须有一种免费发送批量推送的方法。 - user2754681
2个回答

12

我完全同意你的观点,即这个API非常令人沮丧,如果他们可以为每个通知发送一个响应,那么实现起来将会更加容易。

话虽如此,以下是苹果公司建议您执行的操作(来自技术笔记):

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

使用APNs时没有批量大小限制。iOS 6.1新闻发布会宣布自APNs成立以来已发送超过4万亿条推送通知。在WWDC 2012上宣布,APNs每天发送70亿个通知。

如果您看到的吞吐量低于每秒9000个通知,则您的服务器可能会受益于改进的错误处理逻辑。

以下是使用增强二进制接口时检查错误的方法。继续写入直到写入失败。如果流准备好再次写入,请重新发送通知并继续进行。如果流不准备好写入,请查看流是否可供读取。

如果它是,则从流中读取所有可用内容。如果您收到了零字节回复,请注意连接已关闭,因为出现了诸如无效的命令字节或其他解析错误之类的错误。如果您收到六个字节,则为错误响应,您可以检查响应代码和导致错误的通知ID。您需要重新发送该通知之后的每个通知。

一旦所有内容都已发送,请进行最后一次错误响应检查。

由于正常延迟,丢失的连接可能需要一段时间才能从APNs返回您的服务器。在管道已满的情况下,大约有1700个通知写入可能会失败,因此请在流再次准备好写入时重试。

现在,这里的权衡变得有趣了。您可以在每次写操作后检查错误响应,这样您就可以立即捕获错误。但是这会大大增加发送一批通知所需的时间。

如果您已正确捕获设备令牌并将其发送到正确的环境,则几乎所有设备令牌都应该有效。因此,优化假定故障很少发生是有意义的。等待写入失败或批处理完成后再检查错误响应,甚至计算重发丢失通知的时间,您将获得更好的性能。

所有这些都不是特定于APNs的内容,它适用于大多数套接字级编程。

如果您选择的开发工具支持多个线程或进程间通信,则可以拥有一个线程或进程始终等待错误响应,并在应主发送线程或进程知道何时放弃并重试时提醒。


哇,这不是我第一次在苹果技术笔记中发现大量的信息和答案了。感谢您提供的指引! - er0
不用谢。这篇技术笔记已经存在一段时间了,但最近他们添加了我引用的那个部分。 - Eran
@Eran,我在批量发送推送通知时遇到了"broken pipe"错误。我正在使用django-python来发送通知,请问如何避免这个错误?这是我第一次参与这类项目,对很多事情都不太了解,请给出正确的方法以避免这些错误。 - MegaBytes

7

我想以第一人称的角度分享一下我们每天发送数百万APNS通知的经验。

@Eran引用的参考文献是我们在了解苹果如何管理APNS套接字方面最好的资源。对于低容量,它很好,但是苹果的整个文档非常偏向于休闲,低容量的开发人员。一旦你扩展规模,你将看到大量未记录的行为。

该文档中有关异步执行错误检测的部分对于高吞吐量至关重要。如果您坚持在每次发送时阻塞错误,则需要大量并行化您的工作人员以保持吞吐量。然而,推荐的方式是尽可能快地发送,每当出现错误时,进行修复和重放。

我反对那篇文章的一部分是:

如果您已正确捕获设备令牌并将其发送到正确的环境,则几乎所有设备令牌都应该有效。因此,优化假定故障很少是有意义的。

用这样一个巨大的“IF”来预测这个建议似乎非常误导人。我几乎可以保证,大多数开发人员没有100%正确地捕获令牌并处理苹果的反馈服务。即使他们这样做了,该系统本质上是有损失的,因此会发生漂移。

我们看到一些非零的错误#8响应(无效的设备令牌),我将其归因于rooted手机,客户端错误或用户故意欺骗我们的令牌。在过去,我们还看到过许多错误#7(无效的有效负载大小),我们将其追踪到在我们端添加的未正确编码的消息。当然,那是我们的错,但这就是我的观点-说“优化假定失败很少”是向学习开发人员发送错误的信息。我会更愿意说:

假设错误会发生。

希望它们不频繁发生,但要以防万一进行防御性编程。

如果您优化假定错误很少,那么当APNS服务出现问题时,每条消息您发送都将返回错误#10,您的基础设施可能会受到风险的威胁。

问题在于如何正确地响应错误。有关如何正确处理和恢复不同错误的文档含义模糊或缺失。显然留给读者自行解决。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接