APNS 沙箱连接失败 php 文件中的错误“0"? [英] APNS sandbox Connection failed error '0' in php file?

查看:27
本文介绍了APNS 沙箱连接失败 php 文件中的错误“0"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试向我的应用程序发送 Apple 推送通知.我正在关注本教程的 APNS 流程.网址:http://www.raywenderlich.com/3525/apple-push-notification-services-tutorial-part-2.

Am trying to send Apple Push Notifications to my app. Am following this tutorial for the APNS process. URL: http://www.raywenderlich.com/3525/apple-push-notification-services-tutorial-part-2.

我几乎已经完成了 MAMP、PHP 的工作,并且我在 pus_config.php 文件中提到了我的 .pem 文件,用于 APNS 连接.我已经使用 simplepush.php 文件测试了我的 .pem 文件,并向我的设备发送了通知.现在正在尝试使用从上述教程中获取的 push.php 文件.

I have done almost work in MAMP, PHP and i have mentioned my .pem file in pus_config.php file for APNS connection. I have tested my .pem file with simplepush.php file and i sent notifications to my device. Now am trying with push.php file which was taken from the above tutorial.

这是我的 push_config.php 文件,

This is my push_config.php file,

<?php

// Configuration file for push.php

$config = array(
    // These are the settings for development mode
    'development' => array(

        // The APNS server that we will use
        'server' => 'gateway.sandbox.push.apple.com:2195',

        // The SSL certificate that allows us to connect to the APNS servers
        'certificate' => 'GopiAPNSCert.pem',
        'passphrase' => 'gopi',

        // Configuration of the MySQL database 
        'db' => array(
            'host'     => 'localhost',
            'dbname'   => 'gopipush',
            'username' => 'gopipush',
            'password' => 'uH4q9xQGNAuFW',
            ), 

        // Name and path of our log file
        'logfile' => '/Users/gopi/Desktop/PushChatServer/log/push_development.log',
        ),

    // These are the settings for production mode
    'production' => array(

        // The APNS server that we will use
        'server' => 'gateway.push.apple.com:2195',

        // The SSL certificate that allows us to connect to the APNS servers
        'certificate' => 'ck.pem',
        'passphrase' => 'secret',

        // Configuration of the MySQL database
        'db' => array(
            'host'     => 'localhost',
            'dbname'   => 'pushchat',
            'username' => 'pushchat',
            'password' => '1233}jfdoie',
            ),

        // Name and path of our log file
        'logfile' => '/Users/gopi/Desktop/PushChatServer/log/push_development.log',
        ),
    );

以上证书名称和密码已通过 simplepush.php 文件验证和正确测试.

The above certificate name and passphrase are verified and correct tested with simplepush.php file.

这是我的 push.php 文件,

Here is my push.php file,

<?php

try
{
    require_once('push_config.php');

    ini_set('display_errors', 'off');

    if ($argc != 2 || ($argv[1] != 'development' && $argv[1] != 'production'))
        exit("Usage: php push.php development|production". PHP_EOL);

    $mode = $argv[1];
    $config = $config[$mode];

    writeToLog("Push script started ($mode mode)");

    $obj = new APNS_Push($config);
    $obj->start();
}
catch (Exception $e)
{
    fatalError($e);
}

////////////////////////////////////////////////////////////////////////////////

function writeToLog($message)
{
    global $config;
    if ($fp = fopen($config['logfile'], 'at'))
    {
        fwrite($fp, date('c') . ' ' . $message . PHP_EOL);
        fclose($fp);
    }
}

function fatalError($message)
{
    writeToLog('Exiting with fatal error: ' . $message);
    exit;
}

////////////////////////////////////////////////////////////////////////////////

class APNS_Push
{
    private $fp = NULL;
    private $server;
    private $certificate;
    private $passphrase;

    function __construct($config)
    {
        $this->server = $config['server'];
        $this->certificate = $config['certificate'];
        $this->passphrase = $config['passphrase'];

        // Create a connection to the database.
        $this->pdo = new PDO(
            'mysql:host=' . $config['db']['host'] . ';dbname=' . $config['db']['dbname'], 
            $config['db']['username'], 
            $config['db']['password'],
            array());


        // If there is an error executing database queries, we want PDO to
        // throw an exception.
        $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

        // We want the database to handle all strings as UTF-8.
        $this->pdo->query('SET NAMES utf8');
    }

    // This is the main loop for this script. It polls the database for new
    // messages, sends them to APNS, sleeps for a few seconds, and repeats this
    // forever (or until a fatal error occurs and the script exits).
    function start()
    {
        writeToLog('Connecting to ' . $this->server);

        if (!$this->connectToAPNS())
        {
           exit;
        }


        while (true)
        {           
            writeToLog('Getting PushQueue');

            $stmt = $this->pdo->prepare('SELECT * FROM push_queue WHERE time_sent IS NULL LIMIT 20');
            $stmt->execute();
            $messages = $stmt->fetchAll(PDO::FETCH_OBJ);

            foreach ($messages as $message)
            {
                if ($this->sendNotification($message->message_id, $message->device_token, $message->payload))
                {
                    $stmt = $this->pdo->prepare('UPDATE push_queue SET time_sent = NOW() WHERE message_id = ?');
                    $stmt->execute(array($message->message_id));
                }
                else  // failed to deliver
                {
                    $this->reconnectToAPNS();
                }
            }

            unset($messages);           
            sleep(5);
        }
    }

    // Opens an SSL/TLS connection to Apple's Push Notification Service (APNS).
    // Returns TRUE on success, FALSE on failure.
    function connectToAPNS()
    {
        $ctx = stream_context_create();
        stream_context_set_option($ctx, 'ssl', 'local_cert', $this->certificate);
        stream_context_set_option($ctx, 'ssl', 'passphrase', $this->passphrase);


        $this->fp = stream_socket_client(
            'ssl://' . $this->server, $err, $errstr, 60,
            STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);

        if (!$this->fp)
        {
            writeToLog('Failed APNS Connection');
            writeToLog("Failed to connect: $err $errstr");
            return FALSE;
        }

        writeToLog('Connection OK');
        return TRUE;
    }

    // Drops the connection to the APNS server.
    function disconnectFromAPNS()
    {
        fclose($this->fp);
        $this->fp = NULL;
    }

    // Attempts to reconnect to Apple's Push Notification Service. Exits with
    // an error if the connection cannot be re-established after 3 attempts.
    function reconnectToAPNS()
    {
        writeToLog('ReconnectToAPNS');
        $this->disconnectFromAPNS();

        $attempt = 1;

        while (true)
        {
            writeToLog('Reconnecting to ' . $this->server . ", attempt $attempt");

            if ($this->connectToAPNS())
                return;

            if ($attempt++ > 3)
                fatalError('Could not reconnect after 3 attempts');

            sleep(60);
        }
    }

    // Sends a notification to the APNS server. Returns FALSE if the connection
    // appears to be broken, TRUE otherwise.
    function sendNotification($messageId, $deviceToken, $payload)
    {
        if (strlen($deviceToken) != 64)
        {
            writeToLog("Message $messageId has invalid device token");
            return TRUE;
        }

        if (strlen($payload) < 10)
        {
            writeToLog("Message $messageId has invalid payload");
            return TRUE;
        }

        writeToLog("Sending message $messageId to '$deviceToken', payload: '$payload'");

        if (!$this->fp)
        {
            writeToLog('No connection to APNS');
            return FALSE;
        }

        // The simple format
        $msg = chr(0)                       // command (1 byte)
             . pack('n', 32)                // token length (2 bytes)
             . pack('H*', $deviceToken)     // device token (32 bytes)
             . pack('n', strlen($payload))  // payload length (2 bytes)
             . $payload;                    // the JSON payload

        /*
        // The enhanced notification format
        $msg = chr(1)                       // command (1 byte)
             . pack('N', $messageId)        // identifier (4 bytes)
             . pack('N', time() + 86400)    // expire after 1 day (4 bytes)
             . pack('n', 32)                // token length (2 bytes)
             . pack('H*', $deviceToken)     // device token (32 bytes) 
             . pack('n', strlen($payload))  // payload length (2 bytes)
             . $payload;                    // the JSON payload
        */

        $result = @fwrite($this->fp, $msg, strlen($msg));

        if (!$result)
        {
            writeToLog('Message not delivered');
            return FALSE;
        }

        writeToLog('Message successfully delivered');
        return TRUE;
    }
}

在我的 push_development.log 文件中收到此错误.

Am getting this error in my push_development.log file.

2012-05-14T18:04:28+05:30 Push script started (development mode)
2012-05-14T18:04:28+05:30 Connecting to gateway.sandbox.push.apple.com:2195
2012-05-14T18:04:29+05:30 Failed to connect: 0 

我找不到我做错了什么?我应该在我的 push.php 文件中更改什么.我已经测试了我的网络连接和 .pem 文件.你能帮我解决这个错误并在我的设备中收到通知吗?提前致谢.

I can't find what i did wrong? And what i should change in my push.php file. I have tested my network connection and .pem files. Can you please help me to solve this error and get notifications in my device? Thanks in advance.

编辑

unknownc42c032e8297:~ name$ cd /Users/name/Desktop/PushChatServer
unknownc42c032e8297: PushChatServer name$ telnet gateway.sandbox.push.apple.com 2195
Trying 17.149.34.66...
Connected to gateway.sandbox.push-apple.com.akadns.net.
Escape character is '^]'.
^C
Connection closed by foreign host.
unknownc42c032e8297: PushChatServer name$ openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert NameAPNCert.pem -key GopiAPNSCert
.pem
Enter pass phrase for NameAPNKey.pem:
CONNECTED(00000003)
depth=1 /C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
 0 s:/C=US/ST=California/L=Cupertino/O=Apple Inc/OU=Internet Services/CN=gateway.sandbox.push.apple.com
   i:/C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C
 1 s:/C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C
   i:/O=Entrust.net/OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/OU=(c) 1999 Entrust.net Limited/CN=Entrust.net Certification Authority (2048)
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIEZTCCA02gAwIBAgIESyDhfjANBgkqhkiG9w0BAQUFADCBsTELMAkGA1UEBhMC
VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0
Lm5ldC9ycGEgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW
KGMpIDIwMDkgRW50cnVzdCwgSW5jLjEuMCwGA1UEAxMlRW50cnVzdCBDZXJ0aWZp
Y2F0aW9uIEF1dGhvcml0eSAtIEwxQzAeFw0xMDA0MTMyMzM0MzNaFw0xMjA1MzEw
MDA0MjdaMIGPMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTESMBAG
A1UEBxMJQ3VwZXJ0aW5vMRIwEAYDVQQKEwlBcHBsZSBJbmMxGjAYBgNVBAsTEUlu
dGVybmV0IFNlcnZpY2VzMScwJQYDVQQDEx5nYXRld2F5LnNhbmRib3gucHVzaC5h
cHBsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM5NngiDMFpGBMmb
8tG2MRhLEdsx553Xjq+5C/c0mtildwhnC1X0LWKUexWdQsMchniac+WnHFSs3YMJ
JJ55kQSB6wqK/WNcxsUn8pMkMsvk3YZFM7TsaKQvFOeieiXCSJVlR3grm3+dilv1
Br+SUqv8JrgU3ijmoQO63vkb8B/hAgMBAAGjggEnMIIBIzALBgNVHQ8EBAMCBaAw
HQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMDMGA1UdHwQsMCowKKAmoCSG
Imh0dHA6Ly9jcmwuZW50cnVzdC5uZXQvbGV2ZWwxYy5jcmwwMwYIKwYBBQUHAQEE
JzAlMCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5lbnRydXN0Lm5ldDBABgNVHSAE
OTA3MDUGCSqGSIb2fQdLAjAoMCYGCCsGAQUFBwIBFhpodHRwOi8vd3d3LmVudHJ1
c3QubmV0L3JwYTAfBgNVHSMEGDAWgBQe8auJBvhJDwEzd+4Ueu4ZfJMoTTAdBgNV
HQ4EFgQUNyg/64Sjw/+b4YOwC8E/c+jemRgwCQYDVR0TBAIwADANBgkqhkiG9w0B
AQUFAAOCAQEAk9Ij+NCp+323+4vBqbA0fT9ZCROptPqNIshY5uEvaWUaW5hsoLUm
fsMJMueqzDaoj4yPD8iCCZq1Mp8tM8WB2mG1zIxTLshlhRgDDUF11IbUUBHv/ZhU
RzXewQD6pazQmsBPuR0vP3mmWbKqmZOiv2yWSGlQmWGW4m6RQwjYYj8UqqFEdinV
g1+qY6/muTpaCiygDjJZBlv9P6bwwP9FB8OJf5tGECvvxXad3PK/oiI77aLTYSVr
SA0oisXCiqcgTKQq5BV5M3fQQ4ZS73aBKLI0wPYc0AASD5WdtPTGTvmEbhO4KeaU
0SL85Prf8uSsDOLvn3656awLz/H/yzrf/g==
-----END CERTIFICATE-----
subject=/C=US/ST=California/L=Cupertino/O=Apple Inc/OU=Internet Services/CN=gateway.sandbox.push.apple.com
issuer=/C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C
---
No client certificate CA names sent
---
SSL handshake has read 2549 bytes and written 2017 bytes
---
New, TLSv1/SSLv3, Cipher is AES256-SHA
Server public key is 1024 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : AES256-SHA
    Session-ID: 
    Session-ID-ctx: 
    Master-Key: 729CC0899B36143DAC78D40B2C31ECB71C81A3BD8DC5CFD6D71AC7885DD2E63DCD47096E97A1B3AF032A8D7D48BF73DA
    Key-Arg   : None
    Start Time: 1336636910
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---
name
closed

unknownc42c032e8297: PushChatServer name$ php simplepush.php
Connected to APNS
Message successfully delivered

在这里我可以连接 apns 并发送通知.所以认为 .pem 文件没有问题.

Here i able to connect with apns and send notifications. So think no problems with .pem files.

推荐答案

您可以尝试在配置中设置证书文件的绝对路径吗?

Could you try setting the obsolute path to certificate file in config?

您可以检查此项以解决对等验证问题.

You can check this to solve peer verification issue.

安装证书http://code.google.com/p/apns-php/wiki/CertificateCreation#Verify_peer_using_Entrust_Root_Certification_Authority

在这里使用

stream_context_set_option($ctx, 'ssl', 'cafile', 'entrust_2048_ca.cer');

注意:禁用验证也有效.

Note: Disable the verification also works.

这篇关于APNS 沙箱连接失败 php 文件中的错误“0"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆