从我们的服务器发送推送通知时的关键结果

问题描述:

我们在 appstore 上有一个应用程序,并带有注册的推送通知.他们一直成功地工作,但我们现在尝试发送全局"推送,但发生了一些奇怪的事情.这是我们在服务器端 .php 文件中的内容:

We have an app on appstore, and with registered push notifications. They have successfully worked all the time, but we now tried to send a 'global' push, and something weird happened. This is what we have in our server-side .php file:

//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; .这有效.

The code before this has always worked, and it kind of still does. The tokenArray contains the table with tokens, as in SELECT Token FROM Tokens; from our SQL. This works.

在开发过程中,当只注册我们自己的代币时,它总是说消息被传递给 4 个中的 4 个",即使我们已经从手机中删除了我们的应用程序.现在我们尝试使用此代码向所有 ≈1100 个已注册的令牌发送.消息已发送,输出为消息已发送至 1194 个中的 588 个".而我们自己并没有收到通知!这是什么意思?

During development, when only our own tokens were registered, it always said "The message was delivered to 4 out of 4", even though we had deleted our apps from our phones. Now we tried to send to all ≈1100 registered tokens with this code. The message was sent, and the output was "The message was delivered to 588 out of 1194." And we did not receive the notification ourselves! What does that mean?

大约 5 分钟后,我用一个只包含我自己的令牌的数组切换了 tokenArray 并发送了一个新的推送,我在我的手机上收到了那个推送.我还知道一个事实,即前一个失败的tokenArray"中存在工作"令牌(我检查过).

After about 5 minutes, I switched out the tokenArray with an array only containing my own tokens and sent a new push, and I received that one on my phone. I also know for a fact that the 'working' token exist in the previous 'tokenArray' which failed(I checked).

推送通知是一种机会游戏吗!?if($result) 失败是什么意思?为什么它失败了 500 多次?

Is push notification a game of chance!? What does it mean when if($result) fails? And why did it fail over 500 times?

证书和 .pem 和 .p12 等都可以正常工作,我从 push1 到 push2 所做的唯一不同是使用另一个表,该表是我的 SQL 服务器中原始表的克隆.表 2 只有我的令牌,并且有效.没有进行其他更改.只有SELECT Token FROM Tokens2,后来我证明Tokens2中的所有token都存在于Tokens中我不知道是否有人收到了推送,或者仍然安装了该应用程序的 1200 中的幸运"588 收到了.

The certificates and .pem and .p12 etc are all working, the only thing I did different from push1 to push2 was to use another table which is a clone from the original table in my SQL-server. Table2 only have my tokens, and it worked. No other changes was made. Only SELECT Token FROM Tokens2, and later I proved that all the tokens in Tokens2 exist in Tokens I have no idea if anyone got the push at all, or if the 'lucky' 588 of the 1200 that still has the app installed received it.

这是什么原因?我们不敢再发送一个,以防他们中有一半已经收到了.我一次发送推送的速度有限制吗?还是我们做错了什么?!请帮忙,谢谢.

What causes this? We don't dare send another one in case half of them already received it.. Is there some limit to how fast I can send pushes at once? Or what are we doing wrong?! Please help, thanks.

您的主循环没有考虑 Apple 将关闭套接字连接的情况.正如 Eran 所提到的,如果您发送无效令牌,Apple 会在此时关闭连接,任何使用 fwrite 的进一步写入都将失败.因此,如果您的第 589 个令牌无效,则不会向 Apple 发送其他推送.

Your main loop does not take into account cases in which Apple will close socket connections. As mentioned by Eran, if you send an invalid token, Apple closes the connection at which point, any further writes using fwrite will fail. So if your 589th token is invalid, no other push will be sent to Apple.

这是一个适合您逻辑的简单修复方法;这部分替换了主循环中的 if 语句:

Here's a simple fix for that that fits into your logic; this part replaces the if statement in the main loop:

if ($result) {
    $i++;
} else {
    fclose($fp);
    // Add code here to re-open socket-connection with Apple.
}

除了 Eran 提到的增强通知格式之外,您还可以使用 APNS 反馈 API 向 Apple 查询无效令牌并将其从您的数据库中清除.你可以在这里找到更多信息:http://bit.ly/14RPux4

Besides the enhanced notification format mentioned by Eran, you can also use the APNS Feedback API to query Apple for invalid tokens and purge them from your database. You can find more infomation on that here: http://bit.ly/14RPux4

您可以一次发送多少推送通知没有限制.我在几秒钟内发送了数千个.唯一真正的限制是您和 APNS 服务器之间的连接.

There is no limit to how many push notifications you can send at once. I've sent thousands in a few seconds. The only real limitation is the connection between you and the APNS servers.