我们在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包含带有标记的表,如我们的SQL中的SELECT Token FROM Tokens;
。这很有效。
在开发期间,只有我们自己的令牌被注册时,它总是说“消息已经发送到4个中的4个”,即使我们已经从手机中删除了我们的应用程序。现在我们尝试使用此代码发送到所有≈1100个注册的令牌。 消息已发送,输出结果为“消息已传送到1194中的588个”。 我们自己没有收到通知! 这是什么意思?
大约5分钟后,我用一个只包含我自己的令牌的数组切换了tokenArray并发送了一个新的推送,我在手机上收到了一个。我也知道一个事实,即“之前''tokenArray'中存在”工作“令牌失败(我检查过)。
推送通知是机会游戏!? if($result)
失败时意味着什么?为什么它失败超过500次?
证书和.pem和.p12等都在工作,我唯一不同于push1到push2的是使用另一个表,它是我的SQL服务器中原始表的克隆。表2只有我的令牌,它有效。没有进行任何其他更改。只有SELECT Token FROM Tokens2
,后来我证明了Tokens2
中的所有令牌都存在于Tokens
中
我根本不知道是否有人得到了推动,或者如果安装了应用程序的1200的'幸运'588收到了它。
是什么原因引起的?我们不敢发送另一个以防其中一半已经收到它。我可以立即发送推送速度有多少限制?或者我们做错了什么?! 请帮助,谢谢。
答案 0 :(得分:2)
好吧,我不知道php,所以你的代码对我没用。但是,根据您的描述,您的数据库中的某些设备令牌可能无效。当Apple的服务器收到带有无效设备令牌的通知时,它会关闭套接字。如果您在带有错误令牌的消息之后已经写了更多消息,那么它们将无法到达Apple。只有在您检测到套接字已关闭并打开新套接字后,您的消息才能到达Apple。如果您不使用增强的通知格式,最好开始使用它 - 这样您就可以从Apple获取无效消息的ID并从无效令牌中清除您的数据库。但是,即使使用增强格式也不能保证您将检测到所有错误(除非您愿意非常缓慢地发送消息,并在发送每条消息后检查Apple的错误响应)。
答案 1 :(得分:1)
您的主循环未考虑Apple将关闭套接字连接的情况。如Eran所述,如果您发送无效令牌,Apple会关闭此时的连接,使用fwrite进行的任何进一步写入都将失败。因此,如果您的第589个令牌无效,则不会向Apple发送任何其他推送。
这是一个适合你的逻辑的简单修复;这部分取代了主循环中的if语句:
if ($result) {
$i++;
} else {
fclose($fp);
// Add code here to re-open socket-connection with Apple.
}
除了Eran提到的增强型通知格式外,您还可以使用APNS反馈API查询Apple的无效令牌并从数据库中清除它们。您可以在此处找到更多信息:http://bit.ly/14RPux4
您可以一次发送多少推送通知没有限制。我几秒钟就送了几千个。唯一真正的限制是您和APNS服务器之间的连接。