web-dev-qa-db-fra.com

PHP technique pour interroger le serveur de commentaires APNs

Quelqu'un peut-il clarifier ce que les APN (Notification Apple Push) veulent en ce qui concerne la façon dont vous l'interrogez?

Les docs disent que l’envoi commence dès que la connexion est établie. Est-ce que cela signifie que je ne fais pas de fread() dessus?

Voici mon code actuel pour essayer de le lire. Je n'ai PAS mis la fread() dans une boucle car je ne sais pas quelle réponse indique "plus aucun enregistrement à lire" et je ne voulais pas d'une boucle infinie sur mon serveur.

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

Jusqu'à présent, tout ce que je reçois est une réponse nulle. Il n'y a pas d'erreurs, donc c'est la connexion.

Je ne sais pas si la réponse nulle signifie qu'il n'y a pas de données, ou si ma fread() est la mauvaise façon de le faire.

Merci

28
Johnny

Voici un gros casse-tête qui m'a confondu lors de ma première tentative de connexion: les serveurs de commentaires APNS ne renvoient que les jetons de périphérique "ayant expiré" depuis votre dernière demande de commentaires . Ce qui signifie que la plupart du temps, vous obtiendrez une réponse NULL sauf si vous avez déjà affaire à un grand nombre d'utilisateurs de votre application.

Assurez-vous donc de stocker les jetons de périphérique expirés sur un disque ou une base de données, car après votre requête de commentaires, ils sont définitivement partis. Cela rend le test une douleur pour le moins!

Voici une fonction complète permettant de récupérer les jetons de périphérique des serveurs de commentaires APNS (merci beaucoup aux réponses ci-dessus pour m'avoir aidé à tout mettre en place):

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

Si tout va bien, les valeurs de retour de cette fonction ressembleront à ceci (via print_r ()):

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

Ce code semble correct, mais vous devez boucler et vérifier la fin du flux pour pouvoir lire tous les codes de périphérique.

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

Cependant, mon problème est la décompression réelle des données. Est-ce que quelqu'un sait comment décompresser les données binaires que vous venez de lire pour obtenir l'ID de périphérique réel (sous forme de chaîne) avec l'horodatage, etc.?

2
strange

J'ai eu la solution du forum Apple et c'est pour le développement. Essayez ceci pour la production aussi.

"Bien, aussi stupide que cela puisse paraître, j'ai trouvé une solution:

Créez un ID d'application factice dans le portail du programme, activez les notifications Push de développement Créez et téléchargez le profil d'approvisionnement associé Créez un nouveau projet xcode et appelez la méthode registerForRemoteNotificationTypes au démarrage. Installez l'application factice sur votre appareil. À ce stade, vous devez avoir deux applications de DÉVELOPPEMENT en cours d'exécution sur votre appareil: l'application d'origine et l'application factice. Les deux doivent être enregistrés pour recevoir les notifications Push. Désinstallez l'application d'origine et essayez d'envoyer une notification Push à cette application. Appelez le service de feedback et vous devriez recevoir les données en retour. "

1
dsk

Cela a finalement fonctionné pour moi.

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

Et ensuite, il vous suffit de vérifier le jeton de périphérique par rapport à l'horodatage!

0
strange

Je viens juste de commencer à utiliser cette bibliothèque - fonctionne très bien pour moi!

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

0
Steven M