JavaScript EventSource SSE nicht feuern im browser
Ich habe die Entwicklung einer nodejs-server, um server-side-events für eine neue website, die ich bin in der Entwicklung in HTML5.
Wenn ich telnet auf den server ordnungsgemäß funktioniert, senden Sie mir die erforderlichen HTTP-Antwort-Header, gefolgt von einem Strom von Ereignissen, die ich momentan generieren alle 2 oder 3 Sekunden, nur um zu beweisen es funktioniert.
Habe ich versucht die neueste version von FireFox, Chrome und Opera und schaffen Sie die EventSource-Objekt und eine Verbindung zu den nodejs-server OK, aber keiner der Browser generieren Ereignisse, einschließlich der onopen, onmessage und onerror.
Allerdings, wenn ich halt meinen nodejs server, beenden Sie die Verbindung vom Browser, Sie alle plötzlich Versand alle Nachrichten und alle meine Veranstaltungen sind gezeigt. Der Browser dann alle versuchen, eine Verbindung zu dem server als pro spec.
Ich bin hosting-alles auf einen webserver. nichts läuft in den lokalen Dateien.
Habe ich alles gelesen, was ich online finden kann, einschließlich der Bücher, die ich gekauft habe, und nichts deutet auf ein derartiges problem. Gibt es etwas Im fehlt?
Eine Beispiel-server-Implementierung
var http = require('http');
var requests = [];
var server = http.Server(function(req, res) {
var clientIP = req.socket.remoteAddress;
var clientPort = req.socket.remotePort;
res.on('close', function() {
console.log("client " + clientIP + ":" + clientPort + " died");
for(var i=requests.length -1; i>=0; i--) {
if ((requests[i].ip == clientIP) && (requests[i].port == clientPort)) {
requests.splice(i, 1);
}
}
});
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Access-Control-Allow-Origin': '*',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'});
requests.push({ip:clientIP, port:clientPort, res:res});
res.write(": connected.\n\n");
});
server.listen(8080);
setInterval(function test() {
broadcast('poll', "test message");
}, 2000);
function broadcast(rtype, msg) {
var lines = msg.split("\n");
for(var i=requests.length -1; i>=0; i--) {
requests[i].res.write("event: " + rtype + "\n");
for(var j=0; j<lines.length; j++) {
if (lines[j]) {
requests[i].res.write("data: " + lines[j] + "\n");
}
}
requests[i].res.write("\n");
}
}
Eine Beispiel-html-Seite
<!DOCTYPE html>
<html>
<head>
<title>SSE Test</title>
<meta charset="utf-8" />
<script language="JavaScript">
function init() {
if(typeof(EventSource)!=="undefined") {
var log = document.getElementById('log');
if (log) {
log.innerHTML = "EventSource() testing begins..<br>";
}
var svrEvents = new EventSource('/sse');
svrEvents.onopen = function() {
connectionOpen(true);
}
svrEvents.onerror = function() {
connectionOpen(false);
}
svrEvents.addEventListener('poll', displayPoll, false); //display multi choice and send back answer
svrEvents.onmessage = function(event) {
var log = document.getElementById('log');
if (log) {
log.innerHTML += 'message: ' + event.data + "<br>";
}
//absorb any other messages
}
} else {
var log = document.getElementById('log');
if (log) {
log.innerHTML = "EventSource() not supported<br>";
}
}
}
function connectionOpen(status) {
var log = document.getElementById('log');
if (log) {
log.innerHTML += 'connected: ' + status + "<br>";
}
}
function displayPoll(event) {
var html = event.data;
var log = document.getElementById('log');
if (log) {
log.innerHTML += 'poll: ' + html + "<br>";
}
}
</script>
</head>
<body onLoad="init()">
<div id="log">testing...</div>
</body>
</html>
Diese Beispiele sind einfach, aber von der gleichen Sorte wie jede andere demo, die ich gesehen habe in Büchern und online. Die eventSource scheint nur zu funktionieren, wenn ich am Ende eine client-Verbindung, oder beenden Sie den server, aber das wäre polling anstelle von SSE und ich wollen insbesondere die Verwendung SSE.
Interessant, demos, wie die Justizgebäude von html5rock scheinen auch nicht ganz so funktioniert wie erwartet, wenn ich Sie online..
InformationsquelleAutor der Frage Dan | 2012-10-19
Du musst angemeldet sein, um einen Kommentar abzugeben.
geknackt! 🙂
Dank etwas Hilfe von Tom Kersten die mir geholfen haben mit dem testen. Stellt sich heraus, der code ist nicht das problem.
Seid gewarnt.. wenn Ihr client verwendet jede Art von anti-virus-software, die abfängt, web-Anfragen, kann es verursachen hier Probleme. In diesem Fall Sophos Endpoint Security bietet enterprise-Klasse Antiviren-und firewall-Schutz verfügt über ein feature namens web-Schutz. Innerhalb dieser Funktionen ist eine option, um die scan-downloads; es scheint, dass die SSE-Verbindung behandelt wird, als ein download und somit nicht veröffentlicht, um den browser, bis die Verbindung geschlossen und der stream empfangen, zu Scannen. Deaktivieren Sie diese option, heilt das problem. Ich eingereicht haben, einen bug-report, aber auch andere anti-Viren-Systemen können das gleiche tun.
danke für Eure Vorschläge und Hilfe an alle 🙂
InformationsquelleAutor der Antwort Dan
http://www.w3.org/TR/eventsource/#parsing-an-event-stream
Versuchen zu spielen, mit Zeilenenden (
"\r\n"
statt"\n"
).http://www.w3.org/TR/eventsource/#notes
InformationsquelleAutor der Antwort Victor
Modifizierte ich die server-seitige Skript, das "scheint" teilweise funktioniert für Chrome.
Aber die Verbindung-Pause für alle 2 broadcast & nur 1 kann angezeigt werden, auf den client.
Firefox arbeitet für die 1. Sendung stoppen und durch diese Fehlermeldung:
Und Chrome versuchen neu zu verbinden und erhielt die 3. Sendung.
Denke ich, hängt es mit der firewall-Einstellung zu, kann aber nicht erklären, warum irgendwann einmal funktioniert.
Hinweis: Für die Ereignis-listener-Antwort (Zeile 10), 'schließen' & 'Ende' haben unterschiedliche Ergebnis
Sie können es versuchen und mein Ergebnis ist [schließen: 1 Erfolg/2 broadcast -] & [Ende: 1 Erfolg/8 broadcast]
InformationsquelleAutor der Antwort inDream