2014-07-03 5 views
14

Ich arbeite an einem Projekt mit Server-Sent-Events und habe gerade etwas Interessantes entdeckt: Der Verbindungsverlust wird zwischen Chrome und Firefox unterschiedlich gehandhabt.Soll eine EventSource (SSE) versuchen, die Verbindung auf unbestimmte Zeit wiederherzustellen?

Wenn Sie bei Chrome 35 oder Opera 22 die Verbindung zum Server verlieren, versucht es, alle paar Sekunden unbegrenzt neu zu verbinden, bis es erfolgreich ist. Bei Firefox 30 dagegen wird es nur einmal versucht und dann müssen Sie entweder die Seite aktualisieren oder das aufgetretene Fehlerereignis behandeln und die Verbindung manuell wiederherstellen.

Ich bevorzuge die Art und Weise, wie Chrome oder Opera es tut, aber lesen http://www.w3.org/TR/2012/WD-eventsource-20120426/#processing-model, scheint es, als wenn die EventSource versucht, die Verbindung wieder herzustellen und aufgrund eines Netzwerkfehlers fehlschlägt, sollte es die Verbindung nicht erneut versuchen. Nicht sicher, ob ich die Spezifikation richtig verstanden habe.

Ich wurde auf die Anforderung von Firefox für Benutzer festgelegt, vor allem basierend auf der Tatsache, dass Sie nicht mehrere Tabs mit einem Ereignisstrom von der gleichen URL geöffnet in Chrome haben können, aber dieses neue Ergebnis wäre wahrscheinlich ein größeres Problem. Wenn Firefox sich jedoch entsprechend der Spezifikation verhält, könnte ich es auch irgendwie umgehen.

Edit:

Ich werde jetzt Firefox halten Targeting. Dies ist, wie ich bin Umgang mit 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(); 

Antwort

3

ich den Standard auf die gleiche Weise, wie Sie lesen aber, auch wenn sie nicht, da Browser-Bugs sind zu prüfen, Netzwerkfehler, Server, die sterben, sondern halten die Buchse offen, usw. Daher füge ich normalerweise eine Keep-Alive-Funktion über die von SSE bereitgestellte Verbindung hinzu.

Auf der Client-Seite habe ich es mit ein paar Globals und eine Hilfsfunktion zu tun:

var keepaliveSecs = 20; 
var keepaliveTimer = null; 

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

Dann rufe ich gotActivity() an der Spitze der connect(), und dann eine Nachricht jedes Mal, wenn ich bekommen. (connect() im Grunde nur der Anruf

)

Auf der Server-Seite kann es entweder einen Zeitstempel (oder etwas) alle 15 Sekunden, zusätzlich zum normalen Datenfluss ausspucken, oder verwenden Sie einen Timer selbst und spucken aus ein Zeitstempel (oder etwas), wenn der normale Datenfluss für 15 Sekunden ruhig wird.

1

Was mir aufgefallen ist (zumindest in Chrome) ist, dass beim Schließen der SSE-Verbindung mit der Funktion close() nicht versucht wird, die Verbindung erneut herzustellen.

var sse = new EventSource("..."); 
sse.onerror = function() { 
    sse.close(); 
};