0

我遇到了 APNS 问题和一个“阻止”所有后续推送的无效令牌。这是 PHP 中的代码示例:

$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', $cert_path);
$fp = stream_socket_client($ssl_url, $error, $errorString, 2, STREAM_CLIENT_CONNECT, $ctx);
stream_set_blocking($fp, 0);
stream_set_write_buffer($fp, 0);

if (!$fp) {
    while ($message = nextMessage()) {
        $msg = chr(0) . pack("n", 32) . pack('H*', $token) . pack("n", strlen($message)) . $message;
        $fwrite = fwrite($fp, $msg);
    }
    fclose($fp);
}

此代码完美运行

  • 使用一个有效令牌(设备收到消息)
  • 带有许多有效令牌(所有设备都收到了消息)

此外,我不想为每条消息打开/关闭流套接字:它太慢了。

但是,如果使用了无效令牌,则所有跟随无效令牌的设备都不会收到该消息。反馈服务现在没有告诉我任何信息(我可能曾经收到过此令牌无效的信息)。执行“while (!feof($fp)) fread($fp);” 不给我信息。

你能帮我解决这个问题吗?

谢谢你。

4

1 回答 1

2

这就是 Apple 实现推送通知的方式(非常烦人)。如果您发送无效令牌,它们会返回错误响应并关闭套接字。直到你发现socket被关闭了,你可能已经发送了更多的消息,所有这些消息都被丢弃了,需要在你创建一个新的socket之后重新发送。

反馈服务不会帮助你。它返回不再安装您的应用程序的设备的有效设备令牌。它不会返回无效令牌。

以下是 Apple 对此的评价

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

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

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

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

如果是,请从流中读取所有可用的内容。如果返回零字节,则连接因错误(例如无效的命令字节或其他解析错误)而关闭。如果您返回六个字节,这是一个错误响应,您可以检查响应代码和导致错误的通知的 ID。您需要再次发送该通知之后的所有通知。

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

仅仅因为正常的延迟,断开的连接可能需要一段时间才能从 APN 回到您的服务器。由于连接断开,在写入失败之前可以发送超过 500 条通知。大约 1,700 次通知写入可能会因为管道已满而失败,因此在流准备好再次写入时重试。

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

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

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

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

于 2013-06-11T15:29:30.413 回答