Отправить push-уведомление через PHP

Я знаю, что это уже эксплуатируемая тема на SO, но я борюсь с определенной конфигурацией.

Я использую выделенный сервер для отправки push-уведомлений на устройства iOS. С этого сервера я могу успешно подключиться по телнету к шлюзу APNS:

[root@..... luca]# telnet gateway.sandbox.push.apple.com 2195
Trying 17.110.227.35...
Connected to gateway.sandbox.push.apple.com.
Escape character is '^]'.

Я правильно сгенерировал сертификат CA и комбинированный сертификат и ключ от Apple, и я могу проверить соединение OpenSSL, используя их правильно:

[root@... luca]#  openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert server_certificates_bundle_sandbox.pem -key server_certificates_bundle_sandbox.pem -CApath entrust_2048_ca.cer 

CONNECTED(00000003)
depth=2 /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)
verify return:1
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 return:1
depth=0 /C=US/ST=California/L=Cupertino/O=Apple Inc./CN=gateway.sandbox.push.apple.com
verify return:1
---
Certificate chain
 0 s:/C=US/ST=California/L=Cupertino/O=Apple Inc./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-----
.... hidden cert here ....
-----END CERTIFICATE-----
subject=/C=US/ST=California/L=Cupertino/O=Apple Inc./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
---
Acceptable client certificate CA names
/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple Root CA
/C=US/O=Apple Inc./OU=Apple Worldwide Developer Relations/CN=Apple Worldwide Developer Relations Certification Authority
/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple Application Integration Certification Authority
---
SSL handshake has read 3160 bytes and written 2158 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: .... master key here ....
    Key-Arg   : None
    Krb5 Principal: None
    Start Time: 1437564170
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---

Я также могу использовать Mac Os X Pusher для успешной отправки push-уведомлений с использованием этих сертификатов из моего окна разработки.

Я попытался использовать ApnsPHP, используя модифицированную версию их примера кода:

<?php
// Adjust to your timezone
date_default_timezone_set('Europe/Rome');
// Report all PHP errors
error_reporting(-1);
// Using Autoload all classes are loaded on-demand
require_once 'ApnsPHP/ApnsPHP/Autoload.php';
// Instantiate a new ApnsPHP_Push object
$push = new ApnsPHP_Push(
        ApnsPHP_Abstract::ENVIRONMENT_SANDBOX,
        /*'server_certificates_bundle_sandbox.pem'*/
        'server_certificates_bundle_sandbox.pem'
);
// Set the Provider Certificate passphrase
$push->setRootCertificationAuthority('entrust_2048_ca.cer');
// Connect to the Apple Push Notification Service
$push->connect();
// Instantiate a new Message with a single recipient
$message = new ApnsPHP_Message('5ad1fafb8efdec85fc3e51ea0075d342d18bad9e56cf3e014b56ea9fc4f184bd');
// Set a custom identifier. To get back this identifier use the getCustomIdentifier() method
// over a ApnsPHP_Message object retrieved with the getErrors() message.
$message->setCustomIdentifier("Message-Badge-3");
// Set badge icon to "3"
$message->setBadge(3);
// Set a simple welcome text
$message->setText('Hello APNs-enabled device!');
// Play the default sound
$message->setSound();
// Set a custom property
$message->setCustomProperty('acme2', array('bang', 'whiz'));
// Set another custom property
$message->setCustomProperty('acme3', array('bing', 'bong'));
// Set the expiry value to 30 seconds
$message->setExpiry(30);
// Add the message to the message queue
$push->add($message);
// Send all messages in the message queue
$push->send();
// Disconnect from the Apple Push Notification Service
$push->disconnect();
// Examine the error message container
$aErrorQueue = $push->getErrors();
if (!empty($aErrorQueue)) {
        var_dump($aErrorQueue);
}
?>

Это приводит к ошибке при вызове из консоли:

[root@..... luca]# php index.php 
Wed, 22 Jul 2015 13:30:47 +0200 ApnsPHP[19972]: INFO: Trying tls://gateway.sandbox.push.apple.com:2195...
Wed, 22 Jul 2015 13:30:47 +0200 ApnsPHP[19972]: ERROR: Unable to connect to 'tls://gateway.sandbox.push.apple.com:2195':  (0)
Wed, 22 Jul 2015 13:30:47 +0200 ApnsPHP[19972]: INFO: Retry to connect (1/3)...
Wed, 22 Jul 2015 13:30:48 +0200 ApnsPHP[19972]: INFO: Trying tls://gateway.sandbox.push.apple.com:2195...    
Wed, 22 Jul 2015 13:30:49 +0200 ApnsPHP[19972]: ERROR: Unable to connect to 'tls://gateway.sandbox.push.apple.com:2195':  (0)
Wed, 22 Jul 2015 13:30:49 +0200 ApnsPHP[19972]: INFO: Retry to connect (2/3)...
Wed, 22 Jul 2015 13:30:50 +0200 ApnsPHP[19972]: INFO: Trying tls://gateway.sandbox.push.apple.com:2195...    
Wed, 22 Jul 2015 13:30:50 +0200 ApnsPHP[19972]: ERROR: Unable to connect to 'tls://gateway.sandbox.push.apple.com:2195':  (0)
Wed, 22 Jul 2015 13:30:50 +0200 ApnsPHP[19972]: INFO: Retry to connect (3/3)...
Wed, 22 Jul 2015 13:30:51 +0200 ApnsPHP[19972]: INFO: Trying tls://gateway.sandbox.push.apple.com:2195...   
Wed, 22 Jul 2015 13:30:52 +0200 ApnsPHP[19972]: ERROR: Unable to connect to 'tls://gateway.sandbox.push.apple.com:2195':  (0)

Это довольно странно, я пробовал несколько незначительных исправлений, включая удаление раздела verify_peer в Abstract.php, но ни одно из них не сработало. Я что-то упустил здесь, кто-нибудь из вас знает, как это исправить?

Я некоторое время отправлял push-уведомления с Java и Python, поэтому я вполне уверен во всем процессе. В любом случае, это мой первый раз с PHP.


person elbuild    schedule 22.07.2015    source источник
comment
Поддерживает ли ваш PHP SSL и TLS?   -  person Hedam    schedule 22.07.2015
comment
elbuild.com/luca/info.php я думаю, что да. Я прав?   -  person elbuild    schedule 22.07.2015
comment
Да, он поддерживает TLS и SSL.   -  person Hedam    schedule 22.07.2015
comment
У вас есть брандмауэр, блокирующий порты?   -  person Hedam    schedule 22.07.2015
comment
Судя по тому, что я могу подключиться через телнет, я бы сказал, что нет. Вы видели верхнюю часть моего поста?   -  person elbuild    schedule 22.07.2015
comment
Да, но брандмауэры могут зависеть от приложения. Довольно сложно сказать, так как ваши сообщения об ошибках - это просто неспецифические сообщения об ошибках по умолчанию.   -  person Hedam    schedule 22.07.2015
comment
Это мой собственный сервер, я уверен, что там нет брандмауэра.   -  person elbuild    schedule 22.07.2015


Ответы (1)


Я знаю, что это старый пост, но все же я добавляю свои комментарии, чтобы отправить push-уведомление для iOS/iPhone, поскольку однажды я столкнулся с той же проблемой:

Мне удалось подключиться через telnet через сервер Apple Sandbox, но не с помощью скрипта сокета PHP, так как он выдавал ошибку подключения к шлюзу. Пожалуйста, выполните следующие шаги:

  1. Проверьте конфигурацию PHP ( ini ), чтобы убедиться, что SSL и сокет включены.
  2. Нет ограничений, связанных с брандмауэром.
  3. Попробуйте отдельное тестовое уведомление ядра PHP. Вы можете найти его здесь
  4. Теперь openssl должен проверить ваш pem и парольную фразу.

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

person Prashant    schedule 27.09.2015