ошибка отправки Push-уведомлений iOS

Я разработчик приложений iOS и не знаю много о php. Я следую raywenderlich push-уведомлений учебник для создания SSL-сертификатов и закрытого ключа для push-уведомления.

я следовал шагам 3-4 раз, но это не работает. Я проделал те же шаги и раньше, и это сработало.

Я думаю, что проблема в ответе, который я получаю, когда я тестирую подключение к серверу APNS с помощью SSL-сертификата. Я опускаюсь ниже. ответ.

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=iTMS Engineering/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-----
MIIFGzCCBAOgAwIBAgIETBz90jANBgkqhkiG9w0BAQUFADCBsTELMAkGA1UEBhMC
VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0
Lm5ldC9ycGEgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW
KGMpIDIwMDkgRW50cnVzdCwgSW5jLjEuMCwGA1UEAxMlRW50cnVzdCBDZXJ0aWZp
Y2F0aW9uIEF1dGhvcml0eSAtIEwxQzAeFw0xMjA1MjUyMzM3NDZaFw0xNDA1MzEw
NTA4NDhaMIGPMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTESMBAG
A1UEBxMJQ3VwZXJ0aW5vMRMwEQYDVQQKEwpBcHBsZSBJbmMuMRkwFwYDVQQLExBp
VE1TIEVuZ2luZWVyaW5nMScwJQYDVQQDEx5nYXRld2F5LnNhbmRib3gucHVzaC5h
cHBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC/r1z4BRFu
DIU9/vOboVmd7OwaPPLRtcZiZLWxSyG/6KeRPpaeaC6DScvSDRoJuIeTDBup0bg4
08K0Gzh+lfKRlJOC2sma5Wgvk7oP4sty83My3YCZQv4QvgDhx+seONNs6XiA8Cl4
ingDymWGlzb0sTdfBIE/nWiEOtXQZcg6GKePOWXKSYgWyi/08538UihKK4JZIOL2
eIeBwjEwlaXFFpMlStc36uS/8oy+KMjwvuu3HazNMidvbGK2Z68rBnqnOAaDBtuT
K7rwAa5+i8GYY+sJA0DywMViZxgG/xWWyr4DvhtpHfUjyQgg1ixM8q651LNgdRVf
4sB0PfANitq7AgMBAAGjggFZMIIBVTALBgNVHQ8EBAMCBaAwHQYDVR0lBBYwFAYI
KwYBBQUHAwEGCCsGAQUFBwMCMDMGA1UdHwQsMCowKKAmoCSGImh0dHA6Ly9jcmwu
ZW50cnVzdC5uZXQvbGV2ZWwxYy5jcmwwZQYIKwYBBQUHAQEEWTBXMCMGCCsGAQUF
BzABhhdodHRwOi8vb2NzcC5lbnRydXN0Lm5ldDAwBggrBgEFBQcwAoYkaHR0cDov
L2FpYS5lbnRydXN0Lm5ldC9sMWMtY2hhaW4uY2VyMEAGA1UdIAQ5MDcwNQYJKoZI
hvZ9B0sCMCgwJgYIKwYBBQUHAgEWGmh0dHA6Ly93d3cuZW50cnVzdC5uZXQvcnBh
MB8GA1UdIwQYMBaAFB7xq4kG+EkPATN37hR67hl8kyhNMB0GA1UdDgQWBBSgNiNR
qtTShi8PuJ7UNUEbeE71STAJBgNVHRMEAjAAMA0GCSqGSIb3DQEBBQUAA4IBAQAS
EDkUyBHVdRJnCLHY8w9ec92NWqBYqKiSGP0uVCvgpsJIWDBkCGIw1Olks6mQuS9+
R7VRJJFg7EhtufmoRIvjgntKpTe49sB/lrmiZVQGnhjd6YdyYm9+OBUWRvwketLM
v0S+nxZD0qLLJ9foVUB8zP8LtutqFJ5IZw1xb9eSNzhpKkQ9ylj8MCd4tpXZxICL
Gt327poTXwmjQ+31fz7HCQCowMHccP8kiKM5SeYC9q+nkmdaozHVvw4e1RsP+EWO
vPtcH1x1BCkTJajmrO7JuRPLuBEnZGSPUVFRKWP9jy0a28VnJek+oA7rRMRD8irU
fMGbLqkGn8YogdPqe5T1
-----END CERTIFICATE-----
subject=/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=iTMS Engineering/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 2731 bytes and written 2177 bytes
---
New, TLSv1/SSLv3, Cipher is AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : AES256-SHA
    Session-ID: 
    Session-ID-ctx: 
    Master-Key: 0E813189A9AA0F93F3C996DB3D80240F742EB24656AEED9DC18043DCEDD854E9B1C4798098312EB7F6CAB23B10FF343C
    Key-Arg   : None
    Start Time: 1393333259
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)


В начале ответа он выдает ошибку verify error:num=20:unable to get local issuer certificate. В более поздней части ответа также говорится No client certificate CA names sent. Я не знаю этих вещей, но я подозреваю, что проблема заключается в этих ошибках.

EDIT: ошибка, которую я получаю при отправке уведомления с помощью примера PHP-скрипта, приведенного в учебнике.

Warning: stream_socket_client(): Unable to set private key file `/Users/akashpatel/Desktop/SimplePush/ck.pem' in /Users/akashpatel/Desktop/SimplePush/simplepush.php on line 25

Warning: stream_socket_client(): failed to create an SSL handle in /Users/akashpatel/Desktop/SimplePush/simplepush.php on line 25

Warning: stream_socket_client(): Failed to enable crypto in /Users/akashpatel/Desktop/SimplePush/simplepush.php on line 25

Warning: stream_socket_client(): unable to connect to ssl://gateway.sandbox.push.apple.com:2195 (Unknown error) in /Users/akashpatel/Desktop/SimplePush/simplepush.php on line 25
Failed to connect: 0 

EDIT: используя этот app (предложенная Сегев в своем ответе) я проверял ли любая проблема с сертификатом / закрытым ключом. Я мог бы получить уведомление успешно. Поэтому я думаю, что проблема не в сертификате / закрытом ключе.

PHP скрипт, который я использую:

<?php

$deviceToken = 'r34f34f5g45g5y56u76hj676elfjn4urno43f958gh945g8g7';

// Put your private key's passphrase here:
$passphrase = ‘pasphrase’;

// Put your alert message here:
$message = 'Received push notification!';

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

$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);

// Open a connection to the APNS server
$fp = stream_socket_client(
    'ssl://gateway.sandbox.push.apple.com:2195', $err,
    $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);

if (!$fp)
    exit("Failed to connect: $err $errstr" . PHP_EOL);

echo 'Connected to APNS' . PHP_EOL;

// Create the payload body
$body['aps'] = array(
    'alert' => $message,
    'sound' => 'default'
    );

// Encode the payload as JSON
$payload = json_encode($body);

// 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));

if (!$result)
    echo 'Message not delivered' . PHP_EOL;
else
    echo 'Message successfully delivered' . PHP_EOL;

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

EDIT: мой скрипт работает, когда я использую его в производство сервера. Но я буду держать этот вопрос открытым, поскольку он не работает на локальном сервере. Предложения могут помочь другим, для которых он не работает на рабочем сервере.

3 ответов


есть так много вещей, которые идут не так с Push-уведомлением, что вам нужно будет подойти к ним один за другим.

забудьте о php-коде на секунду. Go здесь и скачать последнюю версию.

Это большое крошечное приложение, которое делает все на стороне сервера для вас и отправит push-уведомление на ваше устройство. Если это работает, вы можете продолжить и реализовать php-код, но я подозреваю, что ваша проблема связана с сертификатом приложения \ key.


вижу ошибку:

подключено (00000003) глубина=1 / C=US / O=доверить, Inc./OU=www.доверьтесь.net / rpa включен по ссылке / OU=(c) 2009 Entrust, Inc./ CN=доверить сертификационному органу-l1c проверить ошибка: num=20: невозможно получить сертификат локального эмитента проверить возврат: 0

посмотрите, как вы установили параметр применить контекст к потоку:

$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);

я использовал тот же учебник, что и вы, в разделе troobleshooting прочитайте пулю #3

невозможно получить сертификат локального эмитента. Эта ошибка означает, что не удалось проверить сертификат с сервера. Чтобы исправить это ты необходимо загрузить корневой сертификат Entrust CA. Это можно сделать из терминала с помощью команды: curl-O https://www.entrust.net/downloads/binary/entrust_2048_ca.cer Вы тогда также необходимо добавить stream_context_set_option ($ctx, 'ssl', 'cafile', 'entrust_2048_ca.cer');

скачать entrust_2048_ca.cer

убедитесь, что все ваши cerificate находятся в том же каталоге, что и php-скрипт.

изменить код на следующий:

//applying context to stream option
stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
stream_context_set_option($ctx, 'ssl', 'cafile', 'entrust_2048_ca.cer');

теперь вы должны быть хороши.


Я не знаю, что было проблемой, когда я тестировал с помощью php-скрипта, предоставленного учебником, который я следовал на локальном сервере. Но когда я тестировал с помощью производственного сервера, он отправлял уведомления.