2014-07-03 8 views
14

Pracuję nad projektem wykorzystującym Server-Sent-Events i właśnie natknąłem się na coś interesującego: utrata połączenia jest obsługiwana inaczej w Chrome i Firefox.Czy EventSource (SSE) ma próbować ponownie połączyć się w nieskończoność?

W Chrome 35 lub Operze 22, jeśli utracisz połączenie z serwerem, będzie próbował połączyć się ponownie w nieskończoność co kilka sekund, aż to się uda. Z drugiej strony, na Firefoksie 30 spróbuje tylko jeden raz, a następnie odświeży stronę lub obsłuży wydarzenie błędu i ręcznie ponownie się połączy.

Ja zdecydowanie wolę sposób, w jaki robi to Chrome lub Opera, ale czytając http://www.w3.org/TR/2012/WD-eventsource-20120426/#processing-model wydaje się, że gdy EventSource spróbuje ponownie się połączyć i nie powiedzie się z powodu błędu sieciowego lub innego, nie powinien ponawiać połączenia. Nie jestem pewien, czy poprawnie rozumiem specyfikację.

Byłem zmuszony do korzystania z Firefoksa dla użytkowników, głównie z tego powodu, że nie można mieć wielu kart ze strumieniem wydarzeń z tego samego adresu URL otwartego w Chrome, ale to nowe odkrycie byłoby prawdopodobnie większym problemem. Chociaż, jeśli Firefox zachowuje się zgodnie ze specyfikacją, to równie dobrze mógłbym go obejść.

Edit:

Zamierzam zachować kierowanie Firefoksa teraz. W ten sposób mam obchodzenia reconnections:

var es = null; 
function initES() { 
    if (es == null || es.readyState == 2) { // this is probably not necessary. 
     es = new EventSource('/push'); 
     es.onerror = function(e) { 
      if (es.readyState == 2) { 
       setTimeout(initES, 5000); 
      } 
     }; 
     //all event listeners should go here. 
    } 
} 
initES(); 

Odpowiedz

3

czytam średnia tak samo jak ty, ale nawet jeśli nie, to istnieją błędy przeglądarek do rozważenia, błędy sieciowe, serwery, które padły, ale zachować gniazdo otwarte, itp. Dlatego zazwyczaj dodajemy podtrzymywacz na górze do ponownego połączenia, które zapewnia SSE.

Na stronie klienta zrobić to z kilku globalnych i funkcji pomocniczych:

var keepaliveSecs = 20; 
var keepaliveTimer = null; 

function gotActivity(){ 
if(keepaliveTimer != null)clearTimeout(keepaliveTimer); 
keepaliveTimer = setTimeout(connect,keepaliveSecs * 1000); 
} 

Wtedy nazywamy gotActivity() na szczycie connect(), a następnie za każdym razem pojawia się komunikat. (connect() w zasadzie po prostu wywołuje new EventSource())

Po stronie serwera może wypluwać znacznik czasu (lub coś takiego) co 15 sekund, poza normalnym przepływem danych, lub użyć samego timera i wypluć znacznik czasu (lub coś takiego), jeśli normalny przepływ danych jest spokojny przez 15 sekund.

1

Zauważyłem (przynajmniej w Chrome), że po zamknięciu połączenia SSE za pomocą funkcji close(), nie będzie próbował ponownie nawiązać połączenia.

var sse = new EventSource("..."); 
sse.onerror = function() { 
    sse.close(); 
}; 
Powiązane problemy