APNS+PHP - 超过 200 个令牌无法传递消息

APNS+PHP - Fails to deliver message for more than about 200 tokens

我可以向 APNS 发送关于我数据库中大约前 200 个设备令牌的通知,但在这些消息之后消息失败,这是我的本地服务器日志的一部分,其中发生了伤害:

Processing #234: 153668daa0685d2cb988b6f4a1b5cc0d83ee52772.....<br>Message successfully delivered <br>
Processing #235: 9d9bbce1335de97fe06c4e82000008fad1b88337e.....<br>Message successfully delivered <br>
Processing #236: 74dc41e4e57fe492bdfbfdcda51ae73b217e3a72f.....<br>Message successfully delivered <br>
Processing #237: c8181554e6dc690d8e4a9ce32d1ea9d820d27045d.....<br>Message successfully delivered <br>
Processing #238: 86d86c9415f349647e1d428800dc3a78058775a16.....<br>Message successfully delivered <br>
Processing #239: a31437aa6a8a93ecf3443f2bdb8fa10e6f8c76b59.....<br>Message not delivered <br>
Processing #240: 99df796bc1c604db8adb9b43cb026d3afc97d6d99.....<br>Message not delivered <br>
Processing #241: 109cc26a1562962ec2f0817b9a87855cde3040462.....<br>Message not delivered <br>
Processing #242: 72dc77573e60cd689f05cb4c4b986f6ba8e1747a1.....<br>Message not delivered <br>
Processing #243: ecefedf21b5d08a922e7fec2798f8d08db89a9b43.....<br>Message not delivered <br>
Processing #244: d1d123bf2a3af135c18353a8ec80648b3d74e6231.....<br>Message not delivered <br>

我可以验证消息开始失败的设备令牌 #239 是有效令牌,因为我向其发送了一条消息并且消息已成功送达。

在我的远程服务器中,我得到了一个更详细的错误日志,它是:

Warning: fwrite(): SSL: Broken pipe in 
/myUsernameOnserver/public_html/path/to/file/push.php
on line 51 
Processing #32: d4fbb00733b13d41a2b6bba9f5c5eda14b21babd0.....
Message not delivered

Warning:  fwrite(): SSL operation failed with code 1. OpenSSL Error 
messages:
error:1409F07F:SSL routines:SSL3_WRITE_PENDING:bad write retry in 
/myUsernameOnserver/public_html/path/to/file/push.php
on line 51
Processing #33: d77c5cb283646ed5f480....
Message not delivered <br>

我发送通知的循环代码:

.....above:The connection and preparing of payload
// Encode the payload as JSON
$payload = json_encode($body);

$i = 0;
//Send the Push to each token the close connection
foreach ($deviceTokens as $deviceToken) {
    // Build the binary notification
    $msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;

    // Send it to the server
    $result = fwrite($fp, $msg, strlen($msg));

    echo 'Processing #'.$i.': '.$deviceToken.'<br>';
    $i++;
    if (!$result) {
        echo 'Message not delivered <br>' . PHP_EOL;
            //usleep(400000); //400 msec
        }
    else {
        echo 'Message successfully delivered <br>' . PHP_EOL;
        }
}


// Close the connection to the server
fclose($fp);

....End of function

非常感谢任何帮助。

根据@Nick 回答的正确代码

//Move the connection to a separated function
//to reconnect again easily in case of failing
$fp = connectToAPNS($directory, $passphrase);

$i = 0; //Logging counter

//Send the Push to each token the close connection
foreach ($deviceTokens as $deviceToken) {
        // Build the binary notification
        $msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;

        for ($k = 0 ; $k < 2 ;$k++) { //Number of tries in case of connection interruption
            // Send it to the server
            $result = fwrite($fp, $msg, strlen($msg));

            echo 'Processing #'.$i.': '.$deviceToken.'<br>';
            $i++;
            if (!$result) {
                echo 'Message not delivered at k='.$k.'<br>' . PHP_EOL;
                fclose($fp);
                $fp = connectToAPNS($directory, $passphrase);
            }
            else {
                echo 'Message successfully delivered at k='.$k.'<br>' . PHP_EOL;
                break; //Stop trying 
            }
        }

    }


    // Close the connection to the server
    fclose($fp);

我的日志现在是:

Processing #284: 750e27148b65651f09bccf6617f93c7e8...<br>Message successfully delivered at k=0<br>
Processing #285: 2cdc924bdf8bc786bcc17877a324c79f1...<br>Message successfully delivered at k=0<br>
Processing #286: 48c298ffb890cd2f39e97b4214cb3d42f...<br>Message not delivered at k=0<br>
Connected to APNS <br>
Processing #287: 48c298ffb890cd2f39e97b4214cb3d42f...<br>Message successfully delivered at k=1<br>
Processing #288: 0768350f28f9b7adf64bb97265803838c...<br>Message successfully delivered at k=0<br>
Processing #289: d104e5e51062c568839cc37b4525a024c...<br>Message successfully delivered at k=0<br>

与 APNS 服务器的连接可能因多种原因而被切断。当写入由于这些原因中的任何一个而失败时,您必须重新打开连接。您可以尝试再次将消息发送到同一令牌,但请记住,如果它确实是无效令牌,连接将不断中断。

在您的循环中,当写入失败时,您无需重新打开与 APNS 的连接就可以继续下一个令牌;这是行不通的。添加一些代码以在失败时重新打开连接。您甚至可以添加一些代码来找出写入失败的原因,以确定您是否应该重试当前令牌。您也可以阅读我的回答 here 以获取一些提示。