2012-05-14 3 views
1

내 앱에 Apple Push Notifications를 보내려고합니다. APNS 프로세스에 대한이 자습서를 따르고 있습니까? URL : http://www.raywenderlich.com/3525/apple-push-notification-services-tutorial-part-2.APNS 샌드 박스 연결에 '0'오류가 발생했습니다.

나는 MAMP, PHP에서 거의 작업을 마쳤으며 APNS 연결을위한 pus_config.php 파일에 내 .pem 파일을 언급했다. simplepush.php 파일로 .pem 파일을 테스트했으며 장치에 알림을 보냈습니다. 이제 위 튜토리얼에서 가져온 push.php 파일을 사용해 보겠습니다.

이 내 push_config.php 파일,

<?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 파일 테스트 맞습니다.

여기

<?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 파일에서이 오류가 내 push.php 파일입니다.

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 파일을 테스트했습니다. 이 오류를 해결하고 기기에서 알림을 받도록 도와주십시오. 미리 감사드립니다.

편집 여기

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 파일에 아무런 문제가 없다고 생각하십시오.

+0

if (! is_resource ($ this-> fp)) if this? – Venu

+0

또는 피어 확인 문제 일 수 있습니다. 이것을 확인하십시오 http://code.google.com/p/apns-php/issues/detail?id=1 – Venu

+0

예 Mr.Venu Gopal 제가 push.php 파일에서 코드를 시도했습니다. 하지만 연결 실패 : 내 로그에 0이 있습니다. 이 문제를 해결하도록 도와 주시겠습니까? – Gopinath

답변

3

[EDIT] config의 인증서 파일에 대한 절대 경로를 설정해보세요.

피어 확인 문제를 해결하려면이 확인란을 선택하세요.

인증서를 여기

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

http://code.google.com/p/apns-php/wiki/CertificateCreation#Verify_peer_using_Entrust_Root_Certification_Authority

를 사용하여 설치 : 검증도 작동하지 않도록 설정합니다.

+0

하지만 내 pem 파일이 정상적으로 작동하고 simplepush.php 파일에서 내 장치에 알림을 보냈습니다. 내 질문을 일부 터미널 코드로 편집합니다. – Gopinath

+0

샌드 박스 모드에서 pem이 생성되었는지 확인 하시겠습니까? – Venu

+0

예. apem에서이 .pem 인증서를 사용하여 알림을 받았습니다. 내 질문을 편집하고 알려 드리겠습니다. 당신의 도움의 손길에 감사드립니다. – Gopinath

0

PHP 스크립트가 올바르게 읽을 수 있도록 ck.pem 파일의 사용 권한을 업데이트하는 것이 었습니다. 일단 끝나면 아무 문제없이 APNS에 연결할 수 있습니다.