web-dev-qa-db-ja.com

PHP APNsフィードバックサーバーにクエリを実行する手法

誰かがAPN(Apple Push Notification)が何を望んでいるかを、あなたがそれをどのように照会するかについて明確にすることができますか?

ドキュメントによると、接続が確立されるとすぐに送信が開始されます。これは、私がfread()を実行しないことを意味しますか?

これが私の現在のコードです。 fread()をループに入れなかったのは、「読み取るレコードがこれ以上ない」ことを示す応答がわからず、サーバーで無限ループが発生したくないためです。

_<?php
$apnsCert = 'HOHRO-prod.pem';

$streamContext = stream_context_create();
stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert);
stream_context_set_option($streamContext, 'ssl', 'verify_peer', false);

$apns = stream_socket_client('ssl://feedback.Push.Apple.com:2196', $error, $errorString, 60, STREAM_CLIENT_CONNECT, $streamContext);

echo 'error=' . $error;
echo 'errorString=' . $errorString;


$result = fread($apns, 38);
echo 'result=' . $result;


fclose($apns);
?>
_

これまでのところ、私が得ているのはnull応答だけです。エラーがないので接続中です。

Null応答がデータがないことを意味するのか、それとも私のfread()が間違った方法であるのかわかりません。

ありがとう

29
Johnny

これが私が最初に接続を試みたときに私を混乱させた大きな落とし穴です:APNSフィードバックサーバーは「期限切れ」のデバイストークンのみを返します最後のフィードバックリクエスト以降。つまり、アプリの大量のユーザーを既に処理していない限り、ほとんどの場合、NULL応答が返されます。

したがって、期限切れのデバイストークンは必ずディスクまたはdbに保存してください。フィードバッククエリの後、それらは完全に失われます。これは控えめに言ってもテストを苦痛にします!

APNSフィードバックサーバーからデバイストークンをフェッチするための完全な関数は次のとおりです(すべてをまとめるのに役立つ上記の回答に感謝します)。

function send_feedback_request() {
    //connect to the APNS feedback servers
    //make sure you're using the right dev/production server & cert combo!
    $stream_context = stream_context_create();
    stream_context_set_option($stream_context, 'ssl', 'local_cert', '/path/to/my/cert.pem');
    $apns = stream_socket_client('ssl://feedback.Push.Apple.com:2196', $errcode, $errstr, 60, STREAM_CLIENT_CONNECT, $stream_context);
    if(!$apns) {
        echo "ERROR $errcode: $errstr\n";
        return;
    }


    $feedback_tokens = array();
    //and read the data on the connection:
    while(!feof($apns)) {
        $data = fread($apns, 38);
        if(strlen($data)) {
            $feedback_tokens[] = unpack("N1timestamp/n1length/H*devtoken", $data);
        }
    }
    fclose($apns);
    return $feedback_tokens;
}

すべてが順調である場合、この関数からの戻り値は次のようになります(print_r()を介して):

Array
(
    Array
    (
        [timestamp] => 1266604759
        [length] => 32
        [devtoken] => abc1234..............etcetc
    ),
    Array
    (
        [timestamp] => 1266604922
        [length] => 32
        [devtoken] => def56789..............etcetc
    ),
)
69
Nick Baicoianu

そのコードは正しく見えますが、すべてのデバイスコードを読み取るには、ループしてストリームの終わりを確認する必要があります。

 while (!feof($apns)) {
        $devcon = fread($apns, 38);
 }

しかし、私の問題はデータの実際の解凍です。読んだばかりのバイナリデータを解凍して、タイムスタンプなどとともに実際のデバイスID(文字列として)を取得する方法を知っている人はいますか?

2
strange

Appleフォーラムから解決策を入手しました。これは開発用です。これは、本番環境でも試してみてください。

「まあ、それは馬鹿げているように聞こえますが、私は解決策を見つけました:

プログラムポータルでダミーのアプリIDを作成し、その上で開発プッシュ通知を有効にします。関連するプロビジョニングプロファイルを作成してダウンロードします。新しいxcodeプロジェクトを作成し、開始時にregisterForRemoteNotificationTypesメソッドを呼び出します。デバイスにダミーアプリをインストールします。この時点で、元のアプリとダミーアプリの2つのDEVELOPMENTアプリがデバイスで実行されているはずです。プッシュ通知を受信するには、両方を登録する必要があります。元のアプリをアンインストールし、そのアプリにプッシュ通知を送信してみてください。フィードバックサービスを呼び出すと、データが返されます。」

1
dsk

これはついに私のために働いた。

$arr = unpack("H*", $devconts); 
$rawhex = trim(implode("", $arr));

$feedbackTime = hexdec(substr($rawhex, 0, 8)); 
$feedbackDate = date('Y-m-d H:i', $feedbackTime); 
$feedbackLen = hexdec(substr($rawhex, 8, 4)); 
$feedbackDeviceToken = substr($rawhex, 12, 64);

そして、タイムスタンプに対してデバイストークンをチェックするだけです!

0
strange

このライブラリを使い始めたばかりです-私にとってはうまくいきます!

https://github.com/mac-cain13/notificato

0
Steven M