2016-04-13 6 views
1

Ich habe einen Linux-Server mit Ubuntu 15.10 x64 eingerichtet. Ich habe php/openssl/curl eingerichtet, um mit HTTP/2 zu senden. Das PHP-Skript, mit dem ich gerade teste, ist unten. Im Grunde sende ich zwei Push-Nachrichten, die beide den gleichen Curl-Handle verwenden, um die Verbindung wie von Apple empfohlen offen zu halten. Die erste Nachricht geht durch und erscheint auf meinem Gerät gut, aber wenn es versucht, die zweite Nachricht zu senden, erhalte ich eine Fehlermeldung "Unbekannter SSL-Protokollfehler in Verbindung mit api.development.push.apple.com:443" nach "SSL Sitzungs-ID erneut verwenden ". Hat jemand irgendwelche Vorschläge, was könnte falsch sein? Könnte jemand das Skript ausprobieren und mich wissen lassen, ob sie dasselbe erleben?APNs Provider API HTTP/2 mit PHP, Curl verursacht Fehler auf mehrere Push-Benachrichtigungen gesendet

Im Folgenden sind die Version Ausdrucke von meinem Server:

PHP

PHP 7.0.5-2+deb.sury.org~wily+1 (cli) (NTS) 
Copyright (c) 1997-2016 The PHP Group 
Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies 
with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies 

OpenSSL

OpenSSL 1.0.2d 9 Jul 2015 

curl

curl 7.48.0 (x86_64-pc-linux-gnu) libcurl/7.48.0 OpenSSL/1.0.2d zlib/1.2.8 libidn/1.28 nghttp2/1.10.0-DEV librtmp/2.3 
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp smb smbs smtp smtps telnet tftp 
Features: IDN IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP HTTP2 UnixSockets 

PHP CODE:

<?php 
$ch = curl_init(); 
$device_token = 'TOKEN HERE'; 
$pem_file  = 'YOURFILE.pem'; 
$pem_secret  = 'PEM PASS'; 
$apns_topic  = 'com.YOURTOPIC'; 

//curl_setopt($ch, CURLOPT_SSLVERSION, 6); 
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); 
curl_setopt($ch, CURLOPT_VERBOSE , true); 

echo "Try 1 ================================================" . PHP_EOL; 

//setup and send first push message 
$url = "https://api.development.push.apple.com/3/device/$device_token"; 
curl_setopt($ch, CURLOPT_URL, "{$url}"); 
$sample_alert = '{"aps":{"alert":"hi #1","sound":"default"}}'; 
curl_setopt($ch, CURLOPT_POSTFIELDS, $sample_alert); 

$response = curl_exec($ch); 
$httpcode = curl_getinfo($ch); 
//var_dump($response); 
//var_dump($httpcode); 

echo "Try 2 ================================================" . PHP_EOL; 

//setup and send second push message 
$url = "https://api.development.push.apple.com/3/device/$device_token"; 
curl_setopt($ch, CURLOPT_URL, "{$url}"); 
$sample_alert = '{"aps":{"alert":"hi #2","sound":"default"}}'; 
curl_setopt($ch, CURLOPT_POSTFIELDS, $sample_alert); 

$response = curl_exec($ch); 
$httpcode = curl_getinfo($ch); 
//var_dump($response); 
//var_dump($httpcode); 

curl_close($ch); 

Die Ausgabe der Ausführung des Skripts oben mit curl ausführliche (Personal mit XXXXX ersetzt Artikel):

Try 1 ================================================ 
* Trying 17.110.227.100... 
* Connected to api.development.push.apple.com (17.110.227.100) 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/ssl/certs/ca-certificates.crt 
    CApath: none 
* SSL connection using TLSv1.2/XXXXXXXXXXXXXXXXXXXXXXXXXXX 
* 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 0x555e84417f80) 
> POST /3/device/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 
HTTP/1.1 
Host: api.development.push.apple.com 
Accept: */* 
apns-topic: com.XXXXXXX.XXXXXXXXXXXXXXXXXX 
Content-Length: 43 
Content-Type: application/x-www-form-urlencoded 

* Connection state changed (MAX_CONCURRENT_STREAMS updated)! 
* We are completely uploaded and fine 
< HTTP/2.0 200 
< apns-id:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 
< 
* Connection #0 to host api.development.push.apple.com left intact 
Try 2 ================================================ 
* Found bundle for host api.development.push.apple.com: 0x555e8442afb0 [can multiplex] 
* Hostname api.development.push.apple.com was found in DNS cache 
* Trying 17.110.227.100... 
* Connected to api.development.push.apple.com (17.110.227.100) port 443 (#1) 
* 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/ssl/certs/ca-certificates.crt 
    CApath: none 
* SSL re-using session ID 
* Unknown SSL protocol error in connection to api.development.push.apple.com:443 
* Closing connection 1 
+0

Gelöst: Für jeden, der sich fragte, wie das behoben wurde, musste ich auf 7,47.1 Downrade - Siehe Kommentar Thread unten in der angenommenen Antwort – casmang

Antwort

2

habe ich versucht, den Code und es funktioniert direkt auf meiner Maschine. Trotzdem sehe ich einige Unterschiede zwischen unseren ausführlichen Logs. Das Protokoll von Versuchen 1 ist identisch, aber das Protokoll in Versuch 2 hat einige Unterschiede, das ist meins: „Re-mit-Verbindung bestehende“

... 
Try 2 ================================================ 
* Found bundle for host api.development.push.apple.com: 0x7fe1b380e730 [can multiplex] 
* Re-using existing connection! (#0) with host api.development.push.apple.com 
* Connected to api.development.push.apple.com (17.172.238.203) port 443 (#0) 
* Using Stream ID: 3 (easy handle 0x7fe1b305da00) 
> POST /3/device/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX HTTP/1.1 
Host: api.development.push.apple.com 
Accept: */* 
apns-topic: it.XXX.XXXXX 
Content-Length: 43 
Content-Type: application/x-www-form-urlencoded 

* We are completely uploaded and fine 
< HTTP/2.0 200 
< apns-id:XXXXXXXXXXXXXXXXX 
< 
* Connection #0 to host api.development.push.apple.com left intact 

ich im Log sehe nicht der Text ...

EDIT

Die Lösung scheint curl 7.47.1

+0

Vielen Dank für das Testen für mich! Ich werde das Problem mit dem Thema "Wiederverwendung bestehender Verbindungen" untersuchen. Ich habe wahrscheinlich etwas falsch konfiguriert auf meinem Server, aber es hilft wirklich zu sehen, jemand anderes den gleichen Code versuchen und eine andere Ausgabe bekommen! Vielen Dank! – casmang

+1

Haben Sie versucht, auf Curl 7.47.1 zu downgraden? – valfer

+0

Ich werde es als nächstes versuchen. – casmang

1

hatte dasselbe Problem zu degradieren zu sein. Fand diese Lösung auf Github-Paket beim Graben des Codes, arbeitete für mich. https://github.com/nfilin/apns-http2.

Fügen Sie diese Option Ihren Curl hinzu und versuchen Sie es erneut.

curl_setopt($ch, CURLOPT_SSLKEY, $pem_file); 
curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM'); 
0

Da die akzeptierte Antwort sagt, es funktioniert durch die Herabstufung auf 7.47.1 Cur-... aber nur, wenn alle Nachrichten zurückkehren gesendet einen HTTP 200-Code.

Wenn beispielsweise die zweite Nachricht einen ungültige Nutzlast oder Gerät Token enthält (und, wie erwartet, eine HTTP 4xx Antwort empfangen wird), auf der dritten Nachricht erhält die „Unbekannten SSL-Protokollfehler in Verbindung mit api.development .push.apple.com: 443 ".

Ich vermute, das erwartete Verhalten wäre, eine 4xx auf der zweiten Nachricht zu erhalten, aber nicht die Verbindung zu unterbrechen.

Ein Sub-Standard-Work around wäre, wenn nicht erhalten eine 200 dann trennen und wieder verbinden. Aber ich denke, nach vielen Verbindungsabbrüchen/Verbindungswiederholungen würden wir vom Apple Server verbannt werden.