本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长

+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

暂无数据

当令牌无效时,向 iOS 设备推送通知失败

发布于2024-11-30 20:11     阅读(417)     评论(0)     点赞(23)     收藏(2)


发送推送通知时,它可以正常工作,直到遇到无效的设备 ID(令牌)并且推送通知停止发送。

例如,如果无效令牌位于数组的开头,其余设备将不会收到通知。

有人知道如何阻止这种情况或我应该如何处理无效令牌吗?

无效令牌:

4016d0fb5207c3f7652c499f970a5f0c888f2a733bdaf4965f4de0aa7d4e1d03

有效令牌:

7938f3efb9064a830afce762d843eb5fa67131237ef9a8808b3e2d3c205f530b e9335ed68a4f02c4284ae4b8edfda09fedaff4426c8c017d254c3d52c64ba716 8d3d704618580a065ae4055561b11c662a667113aecd296ed07fe55d0650b596

$tokens = array("4016d0fb5207c3f7652c499f970a5f0c888f2a733bdaf4965f4de0aa7d4e1d03", "7938f3efb9064a830afce762d843eb5fa67131237ef9a8808b3e2d3c205f530b", "e9335ed68a4f02c4284ae4b8edfda09fedaff4426c8c017d254c3d52c64ba716", "8d3d704618580a065ae4055561b11c662a667113aecd296ed07fe55d0650b596");

push_notification($tokens, 0);

function push_notification($tokens, $invalidTokenKey){
    //Setup notification message
    $body = array();
    $body['aps'] = array('alert' => 'My push notification message!');
    $body['aps']['badge'] = 1;

    //Setup stream (connect to Apple Push Server)
    $ctx = stream_context_create();
    stream_context_set_option($ctx, 'ssl', 'passphrase', CERTIFICATES_APNS_PASSPHRASE);
    stream_context_set_option($ctx, 'ssl', 'local_cert', CERTIFICATES_APNS);
    $fp = stream_socket_client('ssl://gateway.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx);
    stream_set_blocking ($fp, 0); //This allows fread() to return right away when there are no errors. But it can also miss errors during last seconds of sending, as there is a delay before error is  returned. Workaround is to pause briefly AFTER sending last notification, and then do one more fread() to see if anything else is there.

    if (!$fp) {
        echo "Failed to connect (stream_socket_client): $err $errstrn";
    } else {
        $apple_expiry = time() + (90 * 24 * 60 * 60); //Keep push alive (waiting for delivery) for 90 days
        for ($i = $invalidTokenKey; $i < count($tokens); $i++) { 
            $apple_identifier = $i;
            $deviceToken = $tokens[$i];
            $payload = json_encode($body);
            //Enhanced Notification
            $msg = pack("C", 1) . pack("N", $apple_identifier) . pack("N", $apple_expiry) . pack("n", 32) . pack('H*', str_replace(' ', '', $deviceToken)) . pack("n", strlen($payload)) . $payload;
            //SEND PUSH
            fwrite($fp, $msg); 
            //We can check if an error has been returned while we are sending, but we also need to check once more after we are done sending in case there was a delay with error response.
            checkAppleErrorResponse($fp);
        }

        //Workaround to check if there were any errors during the last seconds of sending.
        usleep(500000); //Pause for half a second. Note I tested this with up to a 5 minute pause, and the error message was still available to be retrieved

        checkAppleErrorResponse($fp);
        fclose($fp);
    }
}








//FUNCTION to check if there is an error response from Apple
//         Returns TRUE if there was and FALSE if there was not
function checkAppleErrorResponse($fp) {
   //byte1=always 8, byte2=StatusCode, bytes3,4,5,6=identifier(rowID). Should return nothing if OK.
   $apple_error_response = fread($fp, 6);
   //NOTE: Make sure you set stream_set_blocking($fp, 0) or else fread will pause your script and wait forever when there is no response to be sent.

   if ($apple_error_response) {
        //unpack the error response (first byte 'command" should always be 8)
        $error_response = unpack('Ccommand/Cstatus_code/Nidentifier', $apple_error_response);

        if ($error_response['status_code'] == '0') {
            $error_response['status_code'] = '0-No errors encountered';
        } else if ($error_response['status_code'] == '1') {
            $error_response['status_code'] = '1-Processing error';
        } else if ($error_response['status_code'] == '2') {
            $error_response['status_code'] = '2-Missing device token';
        } else if ($error_response['status_code'] == '3') {
            $error_response['status_code'] = '3-Missing topic';
        } else if ($error_response['status_code'] == '4') {
            $error_response['status_code'] = '4-Missing payload';
        } else if ($error_response['status_code'] == '5') {
            $error_response['status_code'] = '5-Invalid token size';
        } else if ($error_response['status_code'] == '6') {
            $error_response['status_code'] = '6-Invalid topic size';
        } else if ($error_response['status_code'] == '7') {
            $error_response['status_code'] = '7-Invalid payload size';
        } else if ($error_response['status_code'] == '8') {
            $error_response['status_code'] = '8-Invalid token';
            $invalidTokenKey =  $error_response['identifier'] + 1;
            push_notification($tokens, $invalidTokenKey);
        } else if ($error_response['status_code'] == '255') {
            $error_response['status_code'] = '255-None (unknown)';
        } else {
            $error_response['status_code'] = $error_response['status_code'] . '-Not listed';
        }
        return true;
   } 
   return false;
}

解决方案


  1. 您应该处理发送无效令牌时引发的错误并继续发送下一个令牌

  2. 您应该处理来自反馈服务(feedback.push.apple.com)的无效令牌,并从令牌列表中删除该令牌

您的示例代码并不关心这些事情,这就是它停止工作的原因。



所属网站分类: 技术文章 > 问答

作者:黑洞官方问答小能手

链接:http://www.phpheidong.com/blog/article/558244/35a14ec7d626fb4621a3/

来源:php黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

23 0
收藏该文
已收藏

评论内容:(最多支持255个字符)