我们在appstore上有一个应用程序,并带有注册的推送通知。他们一直成功地工作,但是我们现在尝试发送“全局”推送,发生了一些奇怪的事情。这就是服务器端.php文件中的内容:
//Loop through tokens in tokenArray
$i = 0;
$t = 0;
foreach($tokenArray as $token)
{
$t++;
// Make notification
$msg = chr(0) . pack('n', 32) . pack('H*', $token) . pack('n', strlen($payload)) . $payload;
// Send
$result;
if($message != null)
{
$result = fwrite($fp, $msg, strlen($msg));
}
if ($result)
$i++;
}
// Close the connection to the server
fclose($fp);
if($i == 0)
{
echo 'The message was not delivered to anyone out of '.$t.'.';
}
else
{
echo 'The message was delivered to '.$i.' out of '.$t.'.';
}
之前的代码一直有效,并且仍然有效。 tokenArray包含带有 token 的表,如SQL中的
SELECT Token FROM Tokens;
所示。这可行。在开发过程中,只有我们自己的 token 被注册时,即使我们已经从手机中删除了我们的应用程序,它始终会说“消息已传递到4个中的4个”。现在,我们尝试使用此代码向所有≈1100个注册 token 发送。
消息已发送,输出为“消息已从1194年传递到588。”
而且我们自己没有收到通知!
这意味着什么?
大约5分钟后,我用仅包含我自己的 token 的数组关闭了tokenArray并发送了一个新的推送,然后我在手机上收到了该推送。我也知道一个事实,在先前失败的“tokenArray”中存在“工作” token (我检查过)。
推送通知是一种机会游戏吗?
if($result)
失败是什么意思?为什么它失败超过500次?证书和.pem和.p12等都可以使用,我所做的与push1到push2不同的唯一事情是使用了另一个表,该表是从我的SQL Server中的原始表克隆来的。表2只有我的 token ,并且可以正常工作。没有其他更改。只有
SELECT Token FROM Tokens2
,后来我证明Tokens2
中的所有标记都存在于Tokens
中我不知道是否有人得到了推动,还是仍然安装了应用程序的1200中的“幸运” 588收到了它。
是什么原因造成的?如果其中一半已经收到,我们不敢再发送一次。.我可以一次发送推送的速度有一定限制吗?还是我们做错了什么?
请帮忙,谢谢。
最佳答案
您的主循环未考虑Apple将关闭套接字连接的情况。如Eran所述,如果您发送了无效的 token ,Apple将在此时关闭连接,使用fwrite进行的任何进一步写入操作都会失败。因此,如果您的第589个 token 无效,则不会有其他推送发送到Apple。
这是适合您逻辑的简单解决方案。这部分替换主循环中的if语句:
if ($result) {
$i++;
} else {
fclose($fp);
// Add code here to re-open socket-connection with Apple.
}
除了Eran提到的增强的通知格式外,您还可以使用APNS反馈API查询Apple无效的 token 并将其从数据库中清除。您可以在这里找到更多信息:http://bit.ly/14RPux4
一次发送多少个推送通知没有限制。我在几秒钟内寄了数千封邮件。唯一真正的限制是您与APNS服务器之间的连接。