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

前端之家收集整理的这篇文章主要介绍了php – 某些设备未收到Apple推送通知前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在使用Apples iOS增强通知格式批量发送推送通知,并使用此帖子中描述的 PHP解决方案: https://stackoverflow.com/a/10059000/300129

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

对正在发生的事情的任何想法都会非常有帮助.

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

虽然我不能给你代码解决你的问题,但我会给你一些建议.

这是您应该使用的逻辑(根据Apple),但我没有设法让它可靠地工作(至少在我的Java实现中没有):

Push Notification Throughput and Error Checking

If you’re seeing throughput lower than 9,000 notifications per second,your server might benefit from improved error handling logic.

Here’s how to check for errors when using the enhanced binary interface. Keep writing until a write fails. If the stream is ready for writing again,resend the notification and keep going. If the stream isn’t ready for writing,see if the stream is available for reading.

If it is,read everything available from the stream. If you get zero bytes back,the connection was closed because of an error such as an invalid command byte or other parsing error. If you get six bytes back,that’s an error response that you can check for the response code and the ID of the notification that caused the error. You’ll need to send every notification following that one again.

Once everything has been sent,do one last check for an error response.

It can take a while for the dropped connection to make its way from APNs back to your server just because of normal latency. It’s possible to send over 500 notifications before a write fails because of the connection being dropped. Around 1,700 notifications writes can fail just because the pipe is full,so just retry in that case once the stream is ready for writing again.

Now,here’s where the tradeoffs get interesting. You can check for an error response after every write,and you’ll catch the error right away. But this causes a huge increase in the time it takes to send a batch of notifications.

Device tokens should almost all be valid if you’ve captured them correctly and you’re sending them to the correct environment. So it makes sense to optimize assuming failures will be rare. You’ll get way better performance if you wait for write to fail or the batch to complete before checking for an error response,even counting the time to send the dropped notifications again.

None of this is really specific to APNs,it applies to most socket-level programming.

If your development tool of choice supports multiple threads or interprocess communication,you could have a thread or process waiting for an error response all the time and let the main sending thread or process know when it should give up and retry.

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

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

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

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

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

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

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

猜你在找的PHP相关文章