某些设备未收到Apple推送通知

时间:2014-02-10 15:34:53

标签: php ios iphone apple-push-notifications apns-php

我正在使用Apples iOS增强型通知格式批量发送推送通知,并使用此帖中描述的PHP解决方案:https://stackoverflow.com/a/10059000/300129

此时的经验是,当我发送推送通知时,某些设备正在接收消息,而某些设备则没有。结果不一致。有时设备X会收到通知,有时设备X不会收到通知。我正在记录所有内容,但我没有收到任何错误回复。

对所发生的事情的任何想法都会非常有帮助。

4 个答案:

答案 0 :(得分:6)

即使 APNS服务器接受了推送通知,也无法保证实际推送推送通知。

就您的服务器而言,推送通知是偶然的;在将通知发送到 APNS 后,无法确定通知的状态。交货时间也可能有所不同,从几秒到半小时          此外,用户的iPhone可能无法始终接收推送通知。它们可能位于 WiFi网络上,不允许连接到 APNS ,因为所需的端口被阻止。或者手机可以关闭。

APNS 会尝试提供该设备收到的 上次通知 online ,但它只会在有限的时间内尝试。一旦超时,推送通知将永远丢失!

答案 1 :(得分:0)

您链接的答案中的解决方案存在问题。它会尝试在每条消息发送后读取错误响应,但读取会立即返回,并且不会等待响应变为可用。虽然这比在每条消息之后等待X mili-seconds的潜在错误响应更有效,但您可能会错过错误响应,Apple可能会在不知道发生任何错误的情况下删除连接。

虽然我无法为您提供解决问题的代码,但我会给您一些建议。

以下是您应该使用的逻辑(根据Apple的说法),但我还没有设法让它可靠地运行(至少在我的Java实现中没有):

  

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

     

如果您发现吞吐量低于每秒9,000个通知,您的服务器可能会从改进的错误处理逻辑中受益。

     

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

     

如果是,请阅读流中的所有内容。如果返回零字节,则由于诸如无效命令字节或其他解析错误之类的错误而关闭连接。如果你得到六个字节,那就是一个错误响应,你可以检查响应代码和导致错误的通知的ID。您需要再次发送该通知后的所有通知。

     

一旦发送完所有内容,请最后一次检查是否有错误响应。

     

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

     

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

     

如果您正确捕获了设备令牌,并且您将它们发送到正确的环境,那么设备令牌几乎都应该有效。因此,优化假设失败是很少见的。如果在检查错误响应之前等待写入失败或批处理完成,即使计算再次发送已删除通知的时间,您也会获得更好的性能。

     

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

     

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

这取自Apple的技术说明:Troubleshooting Push Notifications

我不知道你在PHP中如何检测到写入失败,但是当它发生时,你应该再次尝试写失败的通知,如果它再次失败,请尝试阅读错误响应并关闭连接。

如果您设法阅读错误响应,您将知道哪个通知失败并且您将知道错误类型(最可能的错误是8 - 设备令牌无效)。您提到的答案中的代码在识别出错误后没有做任何事情。 如果在写完100条消息后您收到第80条消息的错误响应,则必须重新发送消息81到100,因为Apple从未收到过消息。在我的情况下(Java服务器),我总是设法读取错误响应(有时我尝试从套接字读取响应时出错)。在这种情况下,我只能继续发送下一个通知(并且无法知道Apple实际收到了哪些通知)。这就是为什么保持数据库清除无效令牌非常重要的原因。

如果你保持你的数据库干净(即只存储由Apple发送到你的应用程序的设备令牌,并且它们都属于相同的推送环境 - 沙盒或生产),你不应该遇到任何无效的设备令牌。

在Java中实现推送通知服务器端时,我遇到了类似的问题。我无法可靠地获得Apple返回的所有错误响应。

我发现在Java中有一种方法可以禁用TCP Nagle算法,这会导致多个消息在批量发送到Apple之前缓冲。虽然Apple鼓励我们使用Nagle的算法(出于性能原因),但我发现当我禁用它然后在我发送给他们的每条消息后尝试读取Apple的响应时,我设法得到100%的错误响应(我通过编写模拟APNS服务器的进程验证了它。)

通过禁用Nagle算法并逐个发送通知,慢慢地,并尝试在每条消息后读取错误响应,您可以找到数据库中的所有无效令牌并将其删除。一旦您知道您的数据库是干净的,您就可以启用Nagle算法并快速恢复发送通知,而无需阅读Apple的错误响应。然后,每当您在向套接字写入消息时出现错误时,您只需创建一个新套接字并重试仅发送最后一条消息。

答案 2 :(得分:0)

我在几个应用程序中也遇到过这个问题。某些设备未收到推送通知的原因可能是:

  • 使用具有生产APNS证书的沙箱APNS服务器。 - >请检查
  • 设备上安装了开发和生产临时配置文件。 - >删除临时,然后你必须等待至少24小时,以便苹果也从其服务器中删除设备令牌。

答案 3 :(得分:0)

就我而言,在开发期间,一些APN未在一台设备中接收(我正在使用PushMeBaby进行测试)。

我从我的设备中删除了与我的项目相关的所有以前的配置文件,从那时起一切都很顺利。要做到这一点,请转到设置>轮廓。

也许我与配置文件存在某种冲突,因为我正在处理的项目已经改变了捆绑包ID和配置文件。

相关问题