28

¿Puede alguien aclarar qué quiere el APN (Apple Push Notification) en cuanto a cómo lo consulta?Técnica de PHP para consultar el Servidor de Comentarios de APN

Los documentos dicen que comienza a enviar tan pronto como se realiza la conexión. ¿Esto significa que no hago un fread() en él?

Aquí está mi código actual para intentar leerlo. NO puse el fread() en un bucle ya que no sé qué respuesta indica "no más registros para leer" y no quería un bucle infinito en mi servidor.

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

Hasta ahora todo lo que recibo es una respuesta nula. No hay errores, entonces se está conectando.

No sé si la respuesta nula significa que no hay datos, o mi fread() es la forma incorrecta de hacerlo.

Gracias

+0

Hoy me encontré con que fread() no funcionará porque la retroalimentación APN envía datos de la basura hasta que la retroalimentación real. Esto hace que el fread falle, porque está leyendo datos nulos/vacíos. Como gw1921 menciona a continuación, debe realizar un bucle en feof() hasta strlen (fread ($ apns, 38)). A partir de ese momento, tendrá comentarios válidos. Luego, descomprime los datos como ha sugerido Nick B a continuación. (Otro problema desagradable: la aplicación desinstalada no generará comentarios a menos que tenga otra aplicación en el dispositivo con el mismo entorno de AP. Por lo tanto, necesita 2 aplicaciones de sandbox activadas por inserción en su dispositivo para que el desinstalado complete los comentarios.) – brack

+0

Incluso tengo un código similar y también obtengo nulo de fread. No estoy seguro de si mi código funciona realmente y APNS está enviando una respuesta NULA o simplemente falta algo. Estoy seguro de que mi conexión con APNS es exitosa. Instalé mi aplicación en unos 5-10 dispositivos y envié un par de alertas, luego desinstalé la aplicación de unos pocos y comencé a enviar las alertas nuevamente para que el servidor de comentarios de APNS nos avisara que no se entregaba en algunos dispositivos. No tengo nada más que espacio en blanco en fread() :-(Si has hecho algo diferente y lo has conseguido, por favor házmelo saber. – Anish

+0

¿Has usado "pushutil"? Una vez que lo encuentras, es una manera más rápida para comprobar el servidor de comentarios. Es una utilidad de Mac OS X que compila y luego ejecuta desde la línea de comandos de Unix. Google Erica Sadun - está en su sitio bajo Push. –

Respuesta

1

Tengo la solución de foro de manzana y es para el desarrollo. Prueba esto también para la producción.

"Bueno, tan tonto como suena, he encontrado una solución:

crear un ID de aplicación maniquí en el portal del programa, activar las notificaciones de desarrollo de empuje en él puede crear y descargar el archivo de suministro asociado Crear un nuevo xcode project, e invoque el método registerForRemoteNotificationTypes al inicio. Instale la aplicación ficticia en su dispositivo. En este punto, debe tener dos aplicaciones DEVELOPMENT ejecutándose en su dispositivo: la aplicación original y la aplicación ficticia. Ambas deben registrarse para recibir push notificaciones. Desinstale la aplicación original e intente enviar una notificación de inserción a esa aplicación. Invoque la retroalimentación. vice, y debería recibir datos de vuelta ".

2

Ese código se ve bien, sin embargo, tiene que realizar un ciclo y verificar el final del flujo para poder leer todos los códigos del dispositivo.

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

Sin embargo, mi problema es el desempaquetado de los datos. ¿Alguien sabe cómo descomprimir los datos binarios que acaba de leer para obtener la identificación del dispositivo real (como cadena) junto con la marca de tiempo, etc.?

+1

Creo que esta es la idea correcta: $ array = unpack ("NnH32", $ result); $ feedbackTime = $ row [0]; $ feedbackLen = $ row [1]; $ feedbackUDID = $ row [2]; que descomprime los 38 bytes enviados por el servidor de comentarios. Sin embargo, el valor de fecha de 32 bits está en orden de red o big-endian. Si alguien puede proporcionar una función de PHP que invierta estos 4 bytes a la orden de Intel (little-endian), creo que tenemos la solución. NOTA: el UDID real es una cadena de caracteres y NO necesita tener su orden invertida. –

+0

¿Esto está bien? --------- /* Convertir flotador HostOrder a la red de pedido */ función FTON ($ val) { $ a = unpack ("I", paquete ("f", $ val)); paquete de devolución ("N", $ a [1]); } /* Convertir flotador de la Orden de red para HostOrder */ función NTOF ($ val) { $ a = unpack ("N", $ val); $ b = desempaquetar ("f", paquete ("I", $ a [1])); return $ b [1]; } – strange

0

Esto finalmente funcionó para mí.

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

¡Y luego simplemente comprueba si el token del dispositivo está en la marca de tiempo!

+0

Esto funciona genial, gw1921. Estoy almacenando el $ feedbackDate en una columna de SQL por el momento.¿Qué tipo de datos debería ser la columna? Lo configuré en Integer y eso me está dando "2009". Las otras 2 columnas, longitud y token, ¡funcionan EXCELENTES! Gracias –

70

Aquí es un gran Gotcha que me confunde cuando se intentó por primera vez la conexión: los servidores de retroalimentación APNS sólo devuelven los tokens de dispositivo que han "expirado" desde su última solicitud de retroalimentación. Lo que significa que la mayoría de las veces obtendrás una respuesta NULA a menos que ya estés lidiando con un gran volumen de usuarios de tu aplicación.

Así que asegúrese de almacenar los tokens de dispositivo caducados en el disco o db, ya que después de su consulta de retroalimentación se han ido para siempre. ¡Esto hace que las pruebas sean dolorosas por decir lo menos!

Aquí es una función completa a buscar a los tokens de dispositivo desde los servidores de retroalimentación APNS (muchas gracias a las respuestas de arriba para ayudarme a poner todo junto):

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 todo va bien, los valores de retorno de esta función se verá algo como esto (a través de print_r()):

Array 
(
    Array 
    (
     [timestamp] => 1266604759 
     [length] => 32 
     [devtoken] => abc1234..............etcetc 
    ), 
    Array 
    (
     [timestamp] => 1266604922 
     [length] => 32 
     [devtoken] => def56789..............etcetc 
    ), 
) 
+0

Gracias por esta elegante solución. Ahora solo necesito saber cómo comparar la marca de tiempo devuelta por el código de comentarios anterior con la marca de tiempo que he guardado en mi base de datos, que por supuesto representa la última vez que el dispositivo me envió un token. ¿Acabo de hacer una comparación de enteros rectos? ¿O tengo que convertir las marcas de tiempo para corregir endianness o algo así? –

+0

Esta respuesta debería ser la solución aceptada, IMO. Esto es básicamente lo que estoy haciendo, y funciona perfectamente. Si todavía no está viendo datos de comentarios con este método, verifique que tenga otra aplicación en el dispositivo con push habilitado que informe al mismo entorno-aps que la aplicación desinstalada. Johnny: con respecto a la marca de tiempo, una vez que la desempaquete como en la publicación de Nick, puede hacer una comparación de enteros. – brack

+1

¿En qué caso no recibiría una respuesta del servidor de comentarios? Mis notificaciones van bien (como puedo decir de los registros) pero por alguna razón nunca recibo ninguna notificación en el dispositivo. – lostInTransit

Cuestiones relacionadas