web-dev-qa-db-ja.com

新しいAPNSプロバイダーAPIおよびPHP

PHPからプッシュ通知を送信するための this に基づくコードの作成を開始しました。

しかし、HTTP/2を使用して応答でフィードバックを提供する新しいAPIがあることを理解したので、そのフィードバックを取得するために何をする必要があるかを考えています。

方向性を示すチュートリアルやサンプルコードを見つけることができませんでした(非常に新しいためだと思います)。

新しいプロバイダーAPIでAPNSに接続するstream_socket_client()メソッドを使用することは可能ですか?フィードバックを取得するにはどうすればよいですか? fwrite($fp, $msg, strlen($msg))から今すぐ返されるのは数字だけです。すべての意図と目的のために、あなたは私のコードを SO私がコードに基づいた質問 からのコードと同じと考えることができます

ありがとう!

19
Ben Holness

新しいHTTP/2 APNSプロバイダーAPIでは、curlを使用してプッシュ通知を送信できます。

[〜#〜] edit [〜#〜]

先に進む前に(@Madoxで指摘されているように)、openssl> = 1.0.2eをインストールする必要があります(できればパッケージから)。コマンドで確認する

openssl version

a)PHPは5.5.24以上でなければなりません。定数CURL_HTTP_VERSION_2_0が定義されます。

b)システムにcurlバージョン7.46+がインストールされていることを確認します

curl --version

c)Curlでhttp/2サポートを有効にする必要があります。前のコマンドを入力したときの出力には、次のような行が表示されます。

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

hTTP2が表示されない場合は、この優れたチュートリアルに従ってcurlにhttp/2をインストールできます https://serversforhackers.com/video/curl-with-http2-support

Curlがopenssl> = 1.0.2eを検出したことを確認します。curl--versionを実行すると、次のように出力されます。

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)すべてをインストールしたら、コマンドラインでテストできます:

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)PHPのサンプルコードを次に示します。

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

}
33
tiempor3al

私はCentOS 6を使用していますが、解決する方法はソースcURLとOpenSSLからインストールすることでした。

とてもシンプルに見えるかもしれませんが、パッケージに適切な構成を見つけるのに3日かかりましたので、私がここでやったことを投稿することで誰かを助けることができると思います。

私はソースからパッケージをインストールするのに慣れていないので、私には少し注意が必要でしたが、HTTPS over HTTP/2を使用してAPNsに接続できるようになりました。

私がしたことの詳細はこちらです:

  1. CURLと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. 次のフラグを使用してOpenSSLを構成します(それらが何をするのかはわかりませんが、私にとってはうまくいきました)。

    export CXXFLAGS="$CXXFLAGS -fPIC"
    ./config zlib enable-ssl3 enable-shared
    
  3. openSSLを作成してインストールする

  4. 次のフラグを使用してcURLを構成します。

    ./configure --with-ssl=/usr/local/ssl/
    
  5. CURLを作成してインストールする

  6. lD_LIBRARY_PATHを/ usr/local/ssl/lib /に設定します

    export LD_LIBRARY_PATH=/usr/local/ssl/lib/                  
    
  7. テスト

    /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
    

結果:

*   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"}

あなたが見ることができるように、私はいを取り除きました

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

Tiempor3alの回答に情報を追加したいと思います。

1)http/2を完全にサポートするには、curlをopensslバージョン> = 1.0.2でコンパイルする必要があります。 CentOSストックopenssl-1.0.1eでコンパイルすると、「?@@?HTTP/2クライアントの序文文字列が見つからないか破損しています...」というエラーが表示されます。

2)phpモジュールmod_curl.soのバージョンがCURL_HTTP_VERSION_2_0定数なしでコンパイルされた場合、整数3に置き換えることができます。

curl_setopt($ch, CURLOPT_HTTP_VERSION, 3);

4
Madox

PHP CURLを使用してHTTP2経由でPushを正常に送信し、応答本文で直接フィードバックを読むことができました(ここでこれを行う方法に関する短いチュートリアルを書きました: HTTP2(およびPHP)でプッシュ通知を送信する )。ソケットから読み取った応答本文を確認できると思います(おそらく「fgets」というphp関数を正確には覚えていません)。

4
valfer

解決する HTTP/2 client preface string missing or corruptエラーPHP 5.6 Apache および [〜#〜] cli [〜#〜] PHP信頼できるDockerイメージ、または自分でDockerfileで行った作業を参照して独自のビルドを作成することができます。同じことがおそらくPHP 7.0にも当てはまりますが、試した。

1
Norbert

このガイド[ http://cloudfields.net/blog/ios-Push-notifications-encryption/] [1] に従って、証明書と秘密キーを生成してマージします。ガイドに記載されているように、同じファイル名でsslcertとpkeyをマージしたら、以下のcurlコマンドを試してください。

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'
1
KeranMarinov