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

我们有一个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包含带有标记的表,如SELECT Token FROM Tokens; 从我们的SQL。 这工作。

在开发过程中,只有我们自己的代币被注册了,它总是说“这个消息已经发送到了4个中的4个”,即使我们已经从我们的手机中删除了我们的应用程序。 现在我们试着用这个代码发送给所有大约1100个注册的令牌。 信息被发送,输出结果是“信息被传送到1194年的588”。 而我们自己也没有收到通知! 那是什么意思?

大约5分钟后,我用一个只包含我自己的标记的数组切换出tokenArray,并发送了一个新的push,然后我在手机上收到了一个。 我也知道一个事实,即'工作'令牌存在于以前的'tokenArray'失败(我检查)。

推通知是一个机会游戏!? if($result)失败,这意味着什么? 为什么它失败了500多次?

证书和.pem和.p12等都在工作,唯一不同的是从push1到push2是使用另一个表,这是从我的SQL服务器的原始表克隆。 表2只有我的令牌,它的工作。 没有其他的改变。 只有SELECT Token FROM Tokens2 ,后来我certificate了Tokens2中的所有令牌Tokens2存在于Tokens我不知道是否有人推送过它,或者如果安装了应用程序的1200的' Tokens2收到了它。

这是什么原因? 我们不敢发送另外一个,以防其中一半已经收到它..是否有一定的限制,我可以一次发送推多快? 或者我们做错了什么? 请帮忙,谢谢。

您的主循环没有考虑到Apple将closures套接字连接的情况。 正如Eran所提到的,如果你发送了一个无效的标记,苹果closures了连接,那么使用fwrite的任何进一步的写入都将失败。 所以如果您的第589个令牌无效,则不会将其他任何推送发送给Apple。

这是适合你的逻辑的一个简单的解决办法; 这部分代替主循环中的if语句:

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

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

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

那么,我不知道PHP,所以你的代码不帮助我。 但是,根据您的描述,您的数据库中可能有一些设备令牌是无效的。 当Apple的服务器收到无效设备令牌的通知时,会closures套接字。 如果你已经在坏标记之后写了更多的消息,他们将不会到达苹果。 只有在您检测到套接字已closures并打开新套接字后,您的邮件才会到达Apple。 如果您不使用增强的通知格式,那么开始使用它将是一个好主意 – 这样您就可以从Apple获取无效消息的ID并清除无效令牌的数据库。 但是,即使使用增强的格式,也不能保证你能检测到所有的错误(除非你真的很慢地发送消息,并且在你发送每条消息之后检查来自Apple的错误响应)。