Ho sviluppato un server nodejs per fornire eventi lato server per un nuovo sito Web che sto sviluppando in HTML5.JavaScript EventSource SSE non attiva nel browser
Quando eseguo il telnet sul server, funziona correttamente, inviando le intestazioni di risposta HTTP necessarie seguite da un flusso di eventi che sto generando ogni 2 o 3 secondi solo per dimostrare che funziona.
Ho provato l'ultima versione di FireFox, Chrome e Opera e creano l'oggetto EventSource e si connettono al server nodejs OK ma nessuno dei browser genera nessuno degli eventi, inclusi onopen, onmessage e onerror.
Tuttavia, se interrompo il mio server nodejs, interrompendo la connessione dai browser, tutti improvvisamente inviano tutti i messaggi e tutti i miei eventi sono mostrati. I browser cercano quindi di riconnettersi al server come da specifiche.
Sto ospitando tutto su un server web. niente è in esecuzione nei file locali.
Ho letto tutto quello che posso trovare online, compresi i libri che ho acquistato e niente indica alcun problema del genere. C'è qualcosa che mi manca?
Un'implementazione server di esempio
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");
}
}
Un campione pagina html
<!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>
Questi esempi sono essenziali ma della stessa varietà come ogni altro demo che ho visto nei libri e in linea. L'eventSource sembra funzionare solo se si termina una connessione client o si termina il server, ma questo sarebbe il polling invece di SSE e in particolare desidero utilizzare SSE.
È interessante notare che, demo, come thouse da html5rock sembrano anche non funzionare del tutto come previsto quando li uso online ..
Dopo aver utilizzato le console Javascript dei vari browser, sembrerebbe che l'EventSource emette un GET/SSE HTTP/1.1 al mio assistente, che si prevede, ma una risposta è non mostrato fino a quando la connessione è chiusa. È questo in base alla progettazione? lo stato della connessione dovrebbe essere keep-alive. EventSource() esegue semplicemente il buffering di tutto ciò che viene inviato fino a quando la pagina viene chiusa o è in attesa di una sorta di marker nei dati che sta ricevendo? – Dan
Oltre al nodo sever, ho anche provato PHP come molti esempi sembrano illustrare quello. Di nuovo, a meno che non chiudi la connessione, questo mostra lo stesso comportamento già menzionato. Sono sorpreso che nessun altro abbia avuto problemi come questo? O sto facendo qualcosa di completamente sbagliato? – Dan
Sembra simile a http://stackoverflow.com/questions/6068820/node-js-problems-with-response-write o http://stackoverflow.com/questions/6258210/how-can-i-output-data- before-i-end-the-response – Victor