Mam następujące zapytanie w jquery. Jest to odczyt adresu "publikuj" pary subskrypcji/publikacji Nginx skonfigurowanej przy użyciu modułu Long Polling Nginx.Chrome nie obsługuje kwerendy ajax jquery
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();
}
});
}
Kod jest częścią pokoju rozmów. Na każdą wysłaną wiadomość odpowiada odpowiedź zerowa (z 200/OK), ale dane są publikowane. To jest kod do odczytu adresu subskrypcji, gdy dane wracają.
Korzystanie z limitu czasu wszystkie osoby na czacie wysyłają prostą wiadomość co 30 do 40 sekund, nawet jeśli nic nie wpisują, więc istnieje wiele danych do przeczytania tego kodu - co najmniej 2 i być może więcej wiadomości na 40 sekund.
Kod jest w 100% skalny w wersjach EI i Firefox. Ale jeden czytany w około 5 nie działa w Chrome.
Gdy Chrome zawiedzie, obowiązuje limit czasu wynoszący 46 sekund.
Dziennik pokazuje jedno/nieaktualne żądanie sieci działania w tym samym czasie.
Przez trzy dni indeksowałem ten kod, próbując różnych pomysłów. I za każdym razem, gdy IE i Firefox działają dobrze, a Chrome zawiedzie.
Jedną z sugestii, którą widziałem, jest wykonanie synchronizacji połączenia - ale jest to oczywiście niemożliwe, ponieważ zablokowałoby to interfejs użytkownika zbyt długo.
Edit - Mam częściowe rozwiązanie: Kod jest teraz ten
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);
}
});
}
Wynik jest czasem odpowiedź jest opóźniona aż opóźnienie $ (15000) dzieje, to w kolejce wiadomości przybyć zbyt quicly do naśladowania. Nie byłem w stanie zrobić tego komunikatu (tylko testowane z wyłączoną opcją netwrok) z tą nową aranżacją.
Bardzo wątpię, że opóźnienia są trudne do problemów z siecią - wszystkie maszyny są maszynami wirtualnymi w mojej prawdziwej maszynie i nie ma innych użytkowników mojej lokalnej sieci LAN.
Edytuj 2 (piątek 2:30 BST) - Zmieniono kod, aby użyć obietnic - a POST działań zaczął pokazywać te same objawy, ale strona odbierająca zaczęła działać poprawnie! (???? !!! ???). To jest procedura POST - obsługuje ona sekwencję żądań, aby zapewnić, że tylko jedna z nich jest wyjątkowa.
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();
});
}
}
Około jedna akcja w 8 Wezwanie do handlechat.php będzie limitu czasu i pojawia się alarm. Po zakończeniu alertu przychodzą wszystkie oczekujące wiadomości w kolejce.
Zauważyłem także, że wywołanie handlechat zostało zatrzymane zanim napisało wiadomość, którą inni zobaczą. Zastanawiam się, czy to może być jakiś dziwny sposób obsługi danych sesji przez php. Wiem, że ostrożnie ustawia kolejki połączeń tak, aby dane sesji nie były uszkodzone, więc starałem się używać różnych przeglądarek lub różnych maszyn. Są tylko 2 wątki robocze PHP, jednak php NIE jest używany w obsłudze/activity lub w obsłudze zawartości statycznej.
Myślałem również, że może to być niedobór pracowników nginx lub procesorów php, więc podniosłem je. Obecnie trudniej jest doprowadzić do niepowodzenia, ale nadal możliwe. Domyślam się, że wywołanie funkcji/activity kończy się niepowodzeniem jeden raz na 30 razy i nie powoduje utraty komunikatów.
Dzięki chłopaki za twój wkład.
Podsumowanie ustaleń.
1) Jest to błąd w Chrome, który był przez jakiś czas w kodzie.
2) Przy odrobinie szczęścia błąd może zostać wyświetlony jako POST, który nie jest wysyłany, a po przekroczeniu czasu pozostawia Chrome w takim stanie, że powtórzony test POST zakończy się pomyślnie.
3) Zmienna używana do przechowywania zwrotu z $ .ajax() może być lokalna lub globalna. Nowe (obietnice) i stare wywołania formatów powodują błąd.
4) Nie znalazłem pracy ani sposobu na uniknięcie błędu.
Ian
Jeśli podejrzewasz, że jest to problem z Chrome, może pomóc innym użytkownikom dowiedzieć się, z której wersji korzystasz. również wersja jQuery. – merv
Chrome 20.0.1132.47 m jquery 1.7.2 O/S 64-bitowe okna na kliencie i Ubuntu 11:04 na serwerze. – Ian
Testowałem to w Safari (5.1.7) i odkryłem, że działa. WIĘC to nie jest problem związany z Webkitem. Próbowano również w wersji 20.0.1132.47 Chrome na Linuksa i to jest problem. – Ian