Nueva API de proveedor de APNS y PHP

Comencé a crear un código basado en esto para enviar notifications push desde PHP.

Sin embargo, ahora que he comprendido que hay una nueva API que utiliza HTTP / 2 y proporciona comentarios en la respuesta, estoy tratando de averiguar qué necesito hacer para get esa información.

No he podido encontrar ningún tutorial o código de ejemplo para darme dirección (supongo que porque es muy nuevo).

¿Es posible usar el método stream_socket_client() para conectarse a APNS con la nueva API de proveedor? ¿Cómo obtengo los comentarios? Todo lo que obtengo de fwrite($fp, $msg, strlen($msg)) este momento es un número. Para todos los bashs y propósitos, puede considerar que mi código sea el mismo que el código de la pregunta SO que basé mi código en

¡Gracias!

Con la nueva API del proveedor HTTP / 2 APNS, puede usar curl para enviar notifications push.

EDITAR

Antes de continuar (como lo indica @Madox), openssl> = 1.0.2e de debe ser instalado (del package preferiblemente). Verificar con el command

 openssl version 

a) Su versión de PHP debe ser> = 5.5.24 para que se defina la constante CURL_HTTP_VERSION_2_0.

b) Asegúrese de tener la versión 7.46+ de curl instalada en su sistema con

 curl --version 

c) Curl debería tener habilitado el soporte http / 2. En la salida al escribir el command anterior, debería ver una línea como esta:

 Features: IDN IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP HTTP2 UnixSockets 

si HTTP2 no aparece, puede seguir este excelente tutorial para instalar http / 2 para curl https://serversforhackers.com/video/curl-with-http2-support

Verifique que el curl detectado openssl> = 1.0.2e, haciendo curl –version debería mostrar algo como esto:

 curl 7.47.1 (x86_64-pc-linux-gnu) libcurl/7.47.1 OpenSSL/1.0.2f zlib/1.2.8 libidn/1.28 nghttp2/1.8.0-DEV librtmp/2.3 

e) Una vez que haya instalado todo, puede probarlo en la línea de command:

 curl -d '{"aps":{"alert":"hi","sound":"default"}}' \ --cert <your-certificate.pem>:<certificate-password> \ -H "apns-topic: <your-app-bundle-id>" \ --http2 \ https://api.development.push.apple.com/3/device/<device-token> 

f) Aquí hay un código de ejemplo en PHP que he probado con éxito:

 if(defined('CURL_HTTP_VERSION_2_0')){ $device_token = '...'; $pem_file = 'path to your pem file'; $pem_secret = 'your pem secret'; $apns_topic = 'your apns topic. Can be your app bundle ID'; $sample_alert = '{"aps":{"alert":"hi","sound":"default"}}'; $url = "https://api.development.push.apple.com/3/device/$device_token"; $ch = curl_init($url); curl_setopt($ch, CURLOPT_POSTFIELDS, $sample_alert); curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0); curl_setopt($ch, CURLOPT_HTTPHEADER, array("apns-topic: $apns_topic")); curl_setopt($ch, CURLOPT_SSLCERT, $pem_file); curl_setopt($ch, CURLOPT_SSLCERTPASSWD, $pem_secret); $response = curl_exec($ch); $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE); //On successful response you should get true in the response and a status code of 200 //A list of responses and status codes is available at //https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/TheNotificationPayload.html#//apple_ref/doc/uid/TP40008194-CH107-SW1 var_dump($response); var_dump($httpcode); } 

Quiero agregar algo de información a la respuesta timer3al.

1) curl se debe comstackr con openssl version> = 1.0.2 para admitir completamente http / 2. Recibo "? @@? Cadena de prefacio del cliente HTTP / 2 faltante o corrupto …" error cuando compilé con CentOS stock openssl-1.0.1e.

2) si su versión del module php mod_curl.so comstackda sin constante CURL_HTTP_VERSION_2_0, podría replacela con el número integer 3:

curl_setopt($ch, CURLOPT_HTTP_VERSION, 3);

Podría enviar correctamente push vía HTTP2 usando php CURL y leer los comentarios directamente en el cuerpo de respuesta (aquí escribí un breve tutorial sobre cómo hacer esto: Enviar notifications push con HTTP2 (y PHP) ). Creo que puedes verificar la lectura del cuerpo de la respuesta desde el zócalo (no recuerdo exactamente la function php, tal vez "fgets").

Estoy usando CentOS 6 y la forma de resolverlo fue instalar desde la fuente cURL y OpenSSL.

Puede parecer muy simple pero me tomó 3 días encontrar la configuration correcta para los packages, así que creo que puedo ayudar a alguien publicando lo que hice aquí.

Resultó un poco difícil para mí, ya que no estoy acostumbrado a instalar packages desde la fuente, pero ahora puedo conectarme a APN utilizando HTTPS a través de HTTP / 2.

Los detalles de lo que hice aquí son:

  1. Descargue y descomprima cURL y OpenSSL:

     wget https://curl.haxx.se/download/curl-7.47.1.tar.gz wget https://www.openssl.org/source/openssl-1.0.2h.tar.gz 
  2. Configure OpenSSL con los siguientes indicadores (no estoy seguro de lo que hacen, pero es lo que funcionó para mí):

     export CXXFLAGS="$CXXFLAGS -fPIC" ./config zlib enable-ssl3 enable-shanetworking 
  3. crear e instalar OpenSSL

  4. Configure cURL con el siguiente indicador:

     ./configure --with-ssl=/usr/local/ssl/ 
  5. Haga e instale cURL

  6. establezca LD_LIBRARY_PATH en / usr / local / ssl / lib /

     export LD_LIBRARY_PATH=/usr/local/ssl/lib/ 
  7. Prueba

     /usr/local/bin/curl -v -d '{"aps":{"alert":"hi","sound":"default"}}' --cert cert.crt --key cert.key -H "apns-topic: topics" --http2 https://api.development.push.apple.com:443/3/device/00fc13adff785122b4ad28809a3420982341241421348097878e577c991de8f0 

El resultado:

 * Trying 17.172.238.203... * Connected to api.development.push.apple.com (17.172.238.203) port 443 (#0) * ALPN, offering h2 * ALPN, offering http/1.1 * Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH * successfully set certificate verify locations: * CAfile: /etc/pki/tls/certs/ca-bundle.crt CApath: none * TLSv1.2 (OUT), TLS header, Certificate Status (22): * TLSv1.2 (OUT), TLS handshake, Client hello (1): * TLSv1.2 (IN), TLS handshake, Server hello (2): * TLSv1.2 (IN), TLS handshake, Certificate (11): * TLSv1.2 (IN), TLS handshake, Server key exchange (12): * TLSv1.2 (IN), TLS handshake, Request CERT (13): * TLSv1.2 (IN), TLS handshake, Server finished (14): * TLSv1.2 (OUT), TLS handshake, Certificate (11): * TLSv1.2 (OUT), TLS handshake, Client key exchange (16): * TLSv1.2 (OUT), TLS handshake, CERT verify (15): * TLSv1.2 (OUT), TLS change cipher, Client hello (1): * TLSv1.2 (OUT), TLS handshake, Finished (20): * TLSv1.2 (IN), TLS change cipher, Client hello (1): * TLSv1.2 (IN), TLS handshake, Finished (20): * SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384 * ALPN, server accepted to use h2 * Server certificate: * subject: CN=api.development.push.apple.com; OU=management:idms.group.533599; O=Apple Inc.; ST=California; C=US * start date: Jun 19 01:49:43 2015 GMT * expire date: Jul 18 01:49:43 2017 GMT * subjectAltName: host "api.development.push.apple.com" matched cert's "api.development.push.apple.com" * issuer: CN=Apple IST CA 2 - G1; OU=Certification Authority; O=Apple Inc.; C=US * SSL certificate verify ok. * Using HTTP2, server supports multi-use * Connection state changed (HTTP/2 confirmed) * TCP_NODELAY set * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0 * Using Stream ID: 1 (easy handle 0x1091110) > POST /3/device/00fc13adff785122b4ad28809a3420982341241421348097878e577c991de8f0 HTTP/1.1 > Host: api.development.push.apple.com > User-Agent: curl/7.48.0 > Accept: */* > apns-topic: topics > Content-Length: 40 > Content-Type: application/x-www-form-urlencoded > * Connection state changed (MAX_CONCURRENT_STREAMS updated)! * We are completely uploaded and fine < HTTP/2.0 400 < * Connection #0 to host api.development.push.apple.com left intact {"reason":"BadDeviceToken"} 

Como puedes ver, me deshice de lo feo

 ▒@@▒HTTP/2 client preface string missing or corrupt. Hex dump for received bytes: 504f5354202f332f6465766963652f746573742048545450 

Siga esta guía [ http://cloudfields.net/blog/ios-push-notifications-encryption/%5D%5B1%5D para generar y combinar su certificate y key privada. Una vez que se fusiona y su sslcert y pkey como se describe en la guía con los mismos nombres de file, intente con el command curl a continuación.

 curl -X POST -H 'apns-topic: com.mycompany.ios.BadassApp' -d '{"aps":{"content-available":1,"alert":"hi","sound":"default"}}' --cert apns_cert.pem:yourCertPassword --http2 'https://api.development.push.apple.com:443/3/device/b8de1sf067effefc398d792205146fc67dn0e96b0ff21ds81cabe384bbe71353' 

Para resolver la HTTP/2 client preface string missing or corrupt errores HTTP/2 client preface string missing or corrupt en PHP 5.6, creé una image de Apache y CLI PHP Docker en la que puede confiar o simplemente busqué lo que hice en Dockerfile para crear la suya. Lo mismo puede aplicarse a PHP 7.0, aunque no lo he probado.

si es posible:

 $errno=0;$errstr=""; $sock = stream_socket_client( "api.push.apple.com:443", $errno, $errstr, 4, STREAM_CLIENT_CONNECT, stream_context_create(["ssl" => ["local_cert" => "/path/to/cert.pem","verify_peer"=>false,"verify_peer_name"=>false]]) ); stream_socket_enable_crypto($sock, true, STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT);