2014-11-25 7 views
9

Ich versuche, eine einfache lange Umfrage in Angularjs durchzuführen - ich mache eine GET-Anfrage und es hängt sich an, bis der Server reagiert. Dann mache ich die Anfrage erneut und warte auf die nächste Antwort - und so weiter.Angularjs lang polling

Aus irgendeinem Grund ist der Code ziemlich unzuverlässig und vermisst etwa 80% der vom Server gesendeten Antworten.

Unten ist mein Code:

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

Gibt es etwas offensichtlich, dass ich hier fehlt?

Der Server kann erkennen, dass der Browser verbunden ist, und der Server sendet zwar eine Antwort, aber der obige Code erhält keine Antwort (keine Konsolenausgabe und kein Fehler). Ich habe versucht, diese Anfrage mit Postboten (Chrome-Erweiterung) zu machen, und die lange Umfrage funktionierte perfekt, also denke ich, dass das Problem irgendwo hier ist.

update: Das Problem tritt nur bei Google Chrome und nur dann auf, wenn es mehr als einen Tab gibt, der die Polling-Funktion gleichzeitig ausführt. Beim Erstellen und Schließen neuer Tabs mit dem Long-Poll gibt es scheinbar zufällige Verhaltensweisen.

+0

Dies ist nur die Hälfte der Geschichte, da Sie weder den Timeout-Code noch den Code für die Server-Seite angegeben haben. Daher ist eine zuverlässige Diagnose schwierig. –

+0

der Timeout-Code? – jitin

Antwort

6

Ich habe herausgefunden, was das verursacht hat. Chrome lädt eine bestimmte URL nur jeweils eine Registerkarte gleichzeitig. Wenn ein Benutzer mehrere Tabs geöffnet hat, die dasselbe Longpoll anfordern, wartet Chrome auf das Beenden des Longpolls auf der ersten Registerkarte, bevor die Abstimmung in der zweiten Registerkarte gestartet wird.

Ich denke, dass der Browser die Long-Poll-Anfrage als "Server, der nicht antwortet" betrachtet. Wenn Sie versuchen, die gleiche Anforderung auf einer neuen Registerkarte zu stellen, führt der Browser diese Anforderung nicht erneut aus, um Ressourcen zu sparen. Wenn Sie auf die Registerkarte Netzwerk schauen, wird eine ausstehende Anfrage angezeigt. Aber das ist eine Lüge, der Browser wartet tatsächlich darauf, dass der Server auf die Anfrage des ersten Tabs antwortet. Sobald es eine Antwort vom Server für die Anfrage des ersten Tabs erhält, fragt es den Server nur nach der Anfrage des zweiten Tabs ab.

Mit anderen Worten, der Browser (Chrome und Opera) wird normalerweise nicht zwei Anfragen mit langer Dauer gleichzeitig an denselben Endpunkt senden - auch wenn diese Anfragen von zwei verschiedenen Registerkarten kommen.

Manchmal entscheidet er sich aber auch nach einer gewissen Zeit, die Anfrage für die zweite Registerkarte zu lösen. Aber ich konnte keine Regel dafür finden. Wenn Sie drei Registerkarten mit der gleichen Anforderung geöffnet haben, führt das Schließen der ersten zu zwei gleichzeitigen Anforderungen von den verbleibenden zwei Registerkarten. Aber wenn Sie 6 Tabs geöffnet haben, verursacht das Schließen des ersten nur 3 gleichzeitige Anfragen und nicht 5. Ich bin mir sicher, dass es einige Regeln für dieses Verhalten geben würde, aber ich denke, wir müssen Code schreiben, vorausgesetzt, dass die Anfragen stattfinden können oder nicht gleichzeitig und der Browser kann warten, bis eine Anfrage beendet ist, bevor an der zweiten gearbeitet wird.

Safari hat dieses Verhalten nicht - es wird mehrere Anfragen gleichzeitig über mehrere Registerkarten machen. Aber Chrome und Opera zeigen dieses Verhalten.

Anstatt also alle Daten gleichzeitig an alle angeschlossenen Clients zu senden, ändere ich jetzt meinen Code, um Zeitstempel zu verwenden, um herauszufinden, wie viele Daten ein Client benötigt, und diese Daten dann zu senden.

+0

Bekannte Problemumgehungen für Chrome/Opera? –

+7

Eine Möglichkeit ist das: Fügen Sie jeder URL ein temporäres zufälliges Suffix hinzu und ignorieren Sie es auf dem Server. Wie folgt: 'localhost: 8080/longpoll?rand = 12345' und ignoriere den Rand-Teil, wenn du die URL im Server analysierst. Auf diese Weise versucht jeder Tab aus der Perspektive des Browsers eine andere URL lang zu pollen (die Rand-Nummer wäre anders) - obwohl es tatsächlich die gleiche URL aus der Perspektive des Servers ist. Daher erhalten Sie gleichzeitige Longpolls auch mit mehreren Tabs. Dies ist eine Möglichkeit, damit umzugehen. – jitin

+2

@rbaghbanli ja und für diesen temporären Teil können Sie den aktuellen Zeitstempel verwenden, er wird jedes Mal einzigartig sein :) –