Tengo la siguiente consulta en jquery. Está leyendo la dirección de "publicación" de un par de suscripción/publicación de Nginx configurado utilizando el módulo de sondeo largo de Nginx.Chrome no maneja la consulta jquery ajax
function requestNextBroadcast() {
// never stops - every reply triggers next.
// and silent errors restart via long timeout.
getxhr = $.ajax({
url: "/activity",
// dataType: 'json',
data: "id="+channel,
timeout: 46000, // must be longer than max heartbeat to only trigger after silent error.
error: function(jqXHR, textStatus, errorThrown) {
alert("Background failed "+textStatus); // should never happen
getxhr.abort();
requestNextBroadcast(); // try again
},
success: function(reply, textStatus, jqXHR) {
handleRequest(reply); // this is the normal result.
requestNextBroadcast();
}
});
}
El código es parte de una sala de chat. Todos los mensajes enviados se responden con una respuesta nula (con 200/OK), pero los datos se publican. Este es el código para leer la dirección de suscripción a medida que los datos vuelven.
Usando un tiempo de espera, todas las personas en la sala de chat están enviando un mensaje simple cada 30 a 40 segundos, incluso si no escriben nada, por lo que hay una gran cantidad de datos para leer este código - al menos 2 y posiblemente más mensajes por 40 segundos.
El código es 100% sólido como una roca en EI y Firefox. Pero uno lee aproximadamente 5 errores en Chrome.
Cuando Chrome falla, tiene 46 segundos de tiempo de espera.
El registro muestra una solicitud de red de actividad pendiente en cualquier momento.
He estado rastreando este código durante 3 días, probando varias ideas. Y cada vez que IE y Firefox funcionan bien y Chrome falla.
Una sugerencia que he visto es hacer que la llamada sea sincrónica, pero eso es claramente imposible porque bloquearía la interfaz de usuario por mucho tiempo.
Editar - Tengo una solución parcial: El código es ahora esto
function requestNextBroadcast() {
// never stops - every reply triggers next.
// and silent errors restart via long timeout.
getxhr = jQuery.ajax({
url: "/activity",
// dataType: 'json',
data: "id="+channel,
timeout: <?php echo $delay; ?>,
error: function(jqXHR, textStatus, errorThrown) {
window.status="GET error "+textStatus;
setTimeout(requestNextBroadcast,20); // try again
},
success: function(reply, textStatus, jqXHR) {
handleRequest(reply); // this is the normal result.
setTimeout(requestNextBroadcast,20);
}
});
}
El resultado es a veces la respuesta se retrasa hasta que el retardo $ (15.000) ocurre, entonces los mensajes en cola llegan demasiado rapidamente a seguir. No he podido hacer que deje caer mensajes (solo probado con netwrok optomisation off) con este nuevo arreglo.
Tengo muchas dudas de que haya demoras debido a problemas de red: todas las máquinas son máquinas virtuales dentro de mi única máquina real, y no hay otros usuarios de mi LAN local.
Editar 2 (viernes 2:30 BST) - Cambió el código para usar promesas - y el POST de acciones comenzó a mostrar los mismos síntomas, ¡pero el lado de recepción comenzó a funcionar bien! (???? !!! ???). Esta es la rutina POST: se trata de una secuencia de solicitudes para garantizar que solo sobresalga una por vez.
function issuePostNow() {
// reset heartbeat to dropout to send setTyping(false) in 30 to 40 seconds.
clearTimeout(dropoutat);
dropoutat = setTimeout(function() {sendTyping(false);},
30000 + 10000*Math.random());
// and do send
var url = "handlechat.php?";
if (postQueue.length > 0) {
postData = postQueue[0];
var postxhr = jQuery.ajax({
type: 'POST',
url: url,
data: postData,
timeout: 5000
})
postxhr.done(function(txt){
postQueue.shift(); // remove this task
if ((txt != null) && (txt.length > 0)) {
alert("Error: unexpected post reply of: "+txt)
}
issuePostNow();
});
postxhr.fail(function(){
alert(window.status="POST error "+postxhr.statusText);
issuePostNow();
});
}
}
Sobre una acción en la llamada a 8 handlechat.php habrá tiempo de espera y aparece la alerta. Una vez que se ha activado la alerta, llegan todos los mensajes en cola.
Y también noté que la llamada de handlechat estaba detenida antes de que escribiera el mensaje que otros verían. Me pregunto si podría ser un manejo extraño de los datos de sesión por php. Sé que pone en cola las llamadas para que los datos de la sesión no estén dañados, así que he tenido cuidado de usar diferentes navegadores o diferentes máquinas. Solo hay 2 subprocesos de php worker, pero php NO se usa en el manejo de/activity ni en el servicio de contenido estático.
También he pensado que podría ser una escasez de trabajadores nginx o procesadores php, así que los he planteado. Ahora es más difícil hacer que las cosas fallen, pero aún es posible. Supongo que la llamada/activity falla ahora una de cada 30 veces y no arroja ningún mensaje.
Y gracias muchachos por su contribución.
Resumen de los resultados.
1) Es un error en Chrome que ha estado en el código por un tiempo.
2) Con suerte, el error puede aparecer como una POST que no se envía y, cuando se agota, deja Chrome en tal estado que una POST repetida tendrá éxito.
3) La variable utilizada para almacenar el retorno de $ .ajax() puede ser local o global. Las nuevas (promesas) y las viejas llamadas de formato activan el error.
4) No he encontrado un trabajo para evitar el error.
Ian
Si sospecha que es un problema de Chrome, podría ayudar a otros a saber qué versión está usando. jQuery versión también. – merv
Chrome 20.0.1132.47 m jquery 1.7.2 Windows de O/S de 64 bits en el cliente y Ubuntu 11:04 en el servidor. – Ian
He estado probando esto en Safari (5.1.7) y he encontrado que funciona. ASÍ QUE no es un problema de Webkit. También probado en la versión 20.0.1132.47 de Chrome para Linux y que tiene el problema. – Ian