30

APNs (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の返信だけです。エラーは出ていないので接続しています。

fread()null 応答がデータがないことを意味するのか、それとも私のやり方が間違っているのかはわかりません。

ありがとう

4

5 に答える 5

69

これは、私が最初に接続を試みたときに私を混乱させた大きな落とし穴です。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
    ),
)
于 2010-02-19T19:08:58.333 に答える
2

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

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

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

于 2009-10-14T15:04:24.570 に答える
1

Appleフォーラムから解決策を得ましたが、それは開発用です。プロダクションでもこれを試してください。

「まあ、ばかげているように聞こえますが、解決策を見つけました。

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

于 2009-10-05T11:49:45.167 に答える
0

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

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

于 2016-02-19T06:59:47.970 に答える
0

これは最終的に私のために働きました。

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

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

于 2009-10-15T20:50:52.680 に答える