La mia app Web utilizza il metodo 'long poll' per tenersi aggiornati con gli ultimi dati dal mio server. Il server risponde solo quando ha nuovi dati, che possono essere molti minuti a parte. (È un sistema di controllo del riscaldamento in cui si vedono solo gli aggiornamenti quando le temperature della stanza cambiano o qualcuno cambia le impostazioni).long-poll jQuery.ajax() non riesce a richiamare dopo il sonno del telefono?
var version = "0";
function updater() {
$.ajax({
type: "POST",
url: "/listen",
data: version,
success: function (data) {
version = handleUpdates(data);
updater();
},
error: function() {
setTimeout(updater, 1000);
}
});
}
Funziona benissimo su browser desktop e telefoni, tranne in un caso. Ho trovato che su telefoni Android con Chrome qualcosa di strano accade dopo che il telefono è andato a dormire per più di circa 10 minuti. La richiesta di posta sembra essere abbandonata, il che credo sia ragionevole dato che il telefono è addormentato. Nella scheda Rete del debugger di Chrome, il testo di stato della richiesta POST dice (annullato).
Il problema si verifica quando si riattiva il telefono mentre la richiesta viene annullata, né viene chiamata la funzione success() o error() e la mia app Web non viene mai aggiornata. $ .ajax() ha rotto la sua promessa per richiamarmi.
Il problema si verifica solo su alcuni dispositivi. Sono stato in grado di fare alcuni test ad hoc prendendo in prestito i dispositivi dagli amici. Finora ho visto solo il problema sui telefoni Android. Ma non è il telefono è collegato a un caricabatterie. Non l'ho visto su nessun tablet, su dispositivi Apple o PC Windows.
Ho provato ad aggiungere un timeout per le impostazioni di Ajax:
timeout: 120 * 1000,
Questo aiuta perché la funzione di errore() è infine chiamato fino a 2 minuti dopo il risveglio. Ma mi piacerebbe che l'utente vedesse gli aggiornamenti entro 1 o 2 secondi. Non voglio rendere il timeout così breve perché creerebbe traffico del server non necessario.
Ho anche provato a rilevare se il dispositivo è in sospensione cercando il ritardo in un secondo setInterval come descritto in Can any desktop browsers detect when the computer resumes from sleep?. Quando rilevo il risveglio, interrompo() il post e ne avvio un altro. Questo aiuta nella maggior parte dei casi. Ma risulta inaffidabile. A volte gli eventi del tempo sembrano mantenere il ticchettio normalmente durante il sonno e la richiesta di posta viene comunque cancellata. E non sembra una soluzione affidabile.
Sto usando l'ultima versione di jQuery: (2.1.2) e Chrome (47).
provare a memorizzare la promessa corrente a livello globale, quindi quando si entra in questo stato fallito, controllare lo stato() della promessa. Cosa contiene? Se contiene qualcosa di diverso da "in sospeso", puoi usarlo combinato con la soluzione di @ spozun per riavviare le cose dopo un periodo di sospensione senza richieste di annullamento inutili. –