2014-11-25 9 views
9

Próbuję wykonać proste żądanie długiej ankiety w Angularjs - wykonuję żądanie GET i trwa ono dopóki serwer nie odpowie. Następnie ponownie zgłoszę żądanie i czekam na kolejną odpowiedź - i tak dalej.Długie sondowanie Angularjs

Jednak z jakiegoś powodu kod jest dość niewiarygodny i pomija około 80% odpowiedzi wysłanych z serwera.

Poniżej jest mój kod:

main.messages=[]; 
... 
main.poll=function(){ 
    $http.get('http://localhost:8080/message') 
    .success(function(data){ 
    console.log(data); 
    main.messages.push(data); 
    main.poll(); 
    }) 
    .error(...) 
}; 

Czy jest coś oczywiste, że jestem tutaj brakuje?

Serwer może wykryć, że przeglądarka jest podłączona, a serwer wysyła odpowiedź, ale powyższy kod nie otrzymuje odpowiedzi (brak wyjścia konsoli i brak błędu). Próbowałem wysyłać tę prośbę z listonoszem (rozszerzenie chrome), a długa ankieta działała doskonale, więc myślę, że problem jest gdzieś tutaj.

aktualizacja: problem występuje tylko w przeglądarce Google Chrome i tylko wtedy, gdy jednocześnie jest wyświetlana więcej niż jedna zakładka z długimi głosowaniami. Istnieje pewne pozornie przypadkowe zachowanie podczas tworzenia i zamykania nowych kart za pomocą długiej ankiety.

+0

To tylko połowa historii, ponieważ nie uwzględniłeś kodu limitu czasu lub kodu po stronie serwera, ponieważ trudno go zdiagnozować w sposób wiarygodny. –

+0

kod limitu czasu? – jitin

Odpowiedz

6

Dowiedziałem się, co było przyczyną tego. Chrome będzie tylko co miesiąc przechodzić pod dany adres URL po jednej karcie. Jeśli użytkownik ma otwarte wiele kart, żądając tego samego długiego czasu, Chrome czeka na zakończenie długiego czasu na pierwszej karcie przed rozpoczęciem ankiety na drugiej karcie.

Wydaje mi się, że przeglądarka analizuje żądanie długich odpytywania jako "serwer, który nie odpowiada". Podczas próby złożenia tego samego żądania w nowej karcie przeglądarka nie ponownie wysyła tego samego żądania w celu zachowania zasobów. Jeśli spojrzysz na kartę sieci, pokaże oczekujące żądanie. Ale to jest "kłamstwo", przeglądarka czeka na odpowiedź serwera na żądanie pierwszej karty. Gdy otrzyma odpowiedź od serwera dla żądania pierwszej karty, tylko wtedy zapyta serwer o żądanie drugiej karty.

Innymi słowy, przeglądarka (Chrome i Opera) zwykle nie wysyła dwóch żądań długiej odpytywania do tego samego punktu końcowego - nawet jeśli te żądania pochodzą z dwóch różnych kart.

Jednak czasami po pewnym czasie decyduje się również zwolnić żądanie dla drugiej karty. Ale nie udało mi się znaleźć żadnej reguły. Jeśli masz 3 otwarte karty z tym samym żądaniem, zamknięcie pierwszego powoduje 2 jednoczesne żądania z pozostałych dwóch kart. Ale jeśli masz otwartych 6 kart, zamknięcie pierwszego powoduje tylko 3 jednoczesne żądania, a nie 5. Jestem pewien, że byłyby pewne reguły rządzące tym zachowaniem, ale myślę, że musimy napisać kod przy założeniu, że żądania mogą lub nie mogą mieć miejsca. jednocześnie przeglądarka może czekać na zakończenie jednego żądania przed rozpoczęciem pracy nad drugim.

Safari nie ma takiego zachowania - będzie wykonywać wiele żądań za pośrednictwem wielu kart jednocześnie. Ale Chrome i Opera pokazują to zachowanie.

Więc zamiast "rozgłaszać" dane jednocześnie do wszystkich podłączonych klientów, zmieniam teraz kod, aby używać znaczników czasu, aby określić, ile danych klient potrzebuje, a następnie wysłać te dane.

+0

Jakieś znane obejścia dla Chrome/Opery? –

+7

Jednym ze sposobów jest: dodać tymczasowy sufiks losowy do każdego adresu URL i zignorować go na serwerze. W ten sposób: 'localhost: 8080/longpoll?rand = 12345' i zignoruj ​​część rand podczas analizowania adresu URL na serwerze. W ten sposób, z perspektywy przeglądarki, każda zakładka próbuje długo odpytać inny URL (numer Rand byłby inny) - nawet jeśli jest to ten sam URL z perspektywy serwera. Dzięki temu uzyskasz równoczesne długopisy nawet z wieloma zakładkami. Jest to jeden sposób radzenia sobie z tym. – jitin

+2

@rbaghbanli tak i dla tej tymczasowej części możesz użyć aktualnego oznaczenia czasu, będzie za każdym razem niepowtarzalny :) –

Powiązane problemy