2010-04-12 11 views
17

Desarrollamos una aplicación para iPhone, y tenemos notificación de inserción para que el desarrollo y la versión ad hoc funcionen correctamente. Pero cuando tratamos de enviar notificaciones automáticas a los dispositivos de usuario reales en nuestra base de datos, obtuvimos el restablecimiento de la conexión SSL, y luego el error Tubo roto. Creemos que tal vez haya demasiados dispositivos en nuestra base de datos (más de 70000), por lo que no se pueden enviar todos los mensajes al mismo tiempo. Así que tratamos de enviar mensajes a 1000 dispositivos una vez, pero aún recibimos este error de "conexión interrumpida" para alrededor de 100 mensajes. Y no estamos seguros de si los mensajes han sido enviados. ¿Cualquier sugerencia?obtener SSL Error de tubería rota cuando tratamos de hacer una notificación de inserción

+0

Estamos teniendo el mismo problema; sin embargo, con 100.000 usuarios. Por lo que sabemos, la notificación llegará a los primeros 100 o así sucesivamente, pero no después de eso. Solo puedo suponer que hay un límite (por recuento o por tiempo) en las notificaciones que se envían. ¿Realmente podría hacer con alguien para confirmar esto? – Wex

Respuesta

18

Hemos resuelto este problema. Se rompe debido a tokens no válidos en nuestra tabla de base de datos. Y el servicio de Apple apns nos desconectará si hay un token no válido. Dado que la conexión está interrumpida, tendrá un error "Broken Pipe" cuando intente enviar mensajes nuevamente. La solución básica es encontrar si la escritura a la tubería es exitosa, si no, simplemente desconecte y reconecte de nuevo después de un poco de retraso.

+11

Ojalá me hubieras explicado cómo codificaste esto - Mona 14 de junio a las 23:52 – Mona

+0

Suele suceder cuando recorro todos los tokens de dispositivo del usuario y si alguno de ellos falla, rompe el tipo de cadena y muestra el mismo error, todos Lo que podemos hacer es clasificar al usuario con un token de dispositivo reciente y verificar la longitud de nuestro extremo, funcionó después de eso. ¡Gracias su respuesta me ayudó!~ –

10

emagic es correcto, una razón para el error de "tubería rota" puede ocurrir a partir de tokens no válidos. Hay algunas otras razones por las que puede ocurrir también. El siguiente es de Apple Technical Note TN2265:

El problema más común es un token de dispositivo no válido. Si el token llegó al desde el entorno de la zona de pruebas, como cuando está probando una compilación de desarrollo en la casa, no puede enviarlo al servicio push de producción. Cada entorno de inserción emitirá un token diferente para el mismo dispositivo o computadora . Si envía un token de dispositivo al entorno equivocado , el servicio push lo verá como un token no válido y descartará la notificación.

Un token de dispositivo no válido también puede significar que el usuario ha eliminado su aplicación desde su dispositivo o computadora. Debe verificar el servicio de comentarios al menos una vez al día para los tokens de dispositivos que ya no son válidos.

Otros posibles problemas pueden ser el envío de una carga útil superior a 256 bytes, es posible que su carga útil no tenga el formato correcto o que su diccionario JSON tenga una sintaxis incorrecta.

Una desconexión ocasional mientras su proveedor está inactivo no es nada preocupado por; solo restablezca la conexión y continúe. Si un de los servidores de inserción está inactivo, el mecanismo de equilibrio de carga direccionará de forma transparente su nueva conexión a otro servidor suponiendo que se conecta por nombre de host y no por dirección IP estática.

1

Extendiéndose sobre la respuesta de emagic, este es mi código php snipplet:

private $fp; 

private function connect(){ 
    $apnsHost  = 'gateway.push.apple.com'; 
    $apnsCert  = 'certs/cert.pem'; 
    $apnsPort  = 2195; 
    $pass   = "blah"; 
    $streamContext = stream_context_create(); 

    stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert); 
    stream_context_set_option($streamContext, 'ssl', 'passphrase', $pass); 
    $this->fp = stream_socket_client('ssl://' . $apnsHost . ':' . $apnsPort, $err, $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $streamContext); 
    if (!$this->fp) return("Failed to connect: $err $errstr<br>"); 
    echo 'Connected to APNS<hr />'; 
    } 

private function send(){ 
    $this->connect(); 
    foreach($pushes as $push) { 
    $payload['aps'] = array('alert' => $push->text, 'badge' => 0, 'sound' => 'default'); 
    $payload2 = json_encode($payload); 
    $msg = chr(0) . pack('n', 32) . pack('H*', $push->token) . pack('n', strlen($payload2)) . $payload2; 
    try { 
     $result = fwrite($this->fp, $msg, strlen($msg)); 
    } 
    catch (\Exception $e) { 
     fclose($this->fp); 
     echo('Error sending payload: ' . $e->getMessage()); 
     sleep(5); 
     $this->connect(); 
    } 
    } 
} 
+0

Estoy tratando de usar esto, pero el try/catch no parece activarse, incluso cuando fwrite() falla. Recibo mensajes de la consola que dicen que no se pudo escribir, pero nunca recibo el mensaje "Error al enviar la carga útil" para enviar. ¿Estás seguro de que fwrite() arroja excepciones? – othomas

+0

Intente eliminar la excepción principal \ from \ ... – JoeGalind

+0

Probé eso, no hace la diferencia. El bloque catch nunca se llama. – othomas

Cuestiones relacionadas