我正在尝试使用服务器发送的事件,因此我的网页可以定期从我的服务器更新时间。问题是我的客户端能够与我的服务器进行交互,但是,我的服务器的响应是不是我的客户端?基本上,当我用firefox打开我的html文件时,我知道我的服务器获取请求然后它开始发送响应,但我的网页上没有显示任何内容......不太确定是什么问题。帮助赞赏!
这是我的客户代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<script>
function init(){
if(typeof(EventSource)!=="undefined"){
var source = new EventSource('localhost');
source.onmessage = function(e) {
document.body.innerHTML += e.data + '<br>';
};
}
else{
document.body.innerHTML = "Sorry, your browser does not support server-sent events...";
}
}
</script>
<body onload="init()">
</body>
</html>
这是我的服务器代码(node.js):
var http = require('http');
var sys = require('sys');
var fs = require('fs');
http.createServer(function(req, res) {
if (req.headers.accept && req.headers.accept == 'text/event-stream') {
sendSSE(req, res);
}).listen(80, "127.0.0.1");
function sendSSE(req, res) {
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
});
var id = (new Date()).toLocaleTimeString();
// Sends a SSE every 5 seconds on a single connection.
setInterval(function() {
constructSSE(res, id, (new Date()).toLocaleTimeString());
}, 5000);
}
function constructSSE(res, id, data) {
res.write('id: ' + id + '\n');
res.write("data: " + data + '\n\n');
}
答案 0 :(得分:0)
您需要添加
res.end();
某处并删除'setInterval'。看起来你正在尝试做的是保持连接活着,在这种情况下你需要显着改变你的代码。查看'net'模块,该模块更适用于“常开”交互式连接。
http://nodejs.org/api/net.html#net_net
http模块设计用于有限的数据交换,请求类型。你试图让它做一些它不打算做的事情。
/*jshint node:true */
var http = require('http');
http.createServer(function (req, res) {
'use strict';
console.log('GOOD request recieved');
res.write('hi there');
res.end();
console.log('GOOD end sent');
}).listen(8888);
http.createServer(function (req, res) {
'use strict';
console.log('BAD request received');
res.write('hi there');
console.log('BAD response wrote not ending');
}).listen(8889);
考虑我上面的两台服务器。如果使用节点客户端代码对它们进行ping操作,您将看到两者都有数据,并且应该在发送时看到块。但是,如果您尝试使用浏览器ping 8889,则网页将永远不会呈现,因为永远不会发送结束事件。浏览器依赖于此来了解已收到的所有内容。如果你的客户端代码在浏览器中工作,这可能会影响一些事情。尝试首先对您的服务器使用普通的NodeJS客户端代码,并确保数据以您期望的方式发送。然后研究浏览器如何扰乱事物。我的猜测是,数据会被浏览器接收,但它从不对它做任何事情,并等待为该'end'事件分发它,就像8889服务器的网页永远不会呈现的那样......它相信有更多的数据需要等待。
示例客户端代码:
var options = {
hostname: '127.0.0.1',
method: 'GET'
};
options.port = 8888;
http.request(options, function (res) {
'use strict';
console.log('GOOD Pinged server');
res.on('data', function (chunk) {
console.log('GOOD data chunk:' + chunk);
});
res.on('end', function () {
console.log('GOOD end event recieved');
});
}).end();
options.port = 8889;
http.request(options, function (res) {
'use strict';
console.log('BAD Pinged server');
res.on('data', function (chunk) {
console.log('BAD data chunk:' + chunk);
});
res.on('end', function () {
console.log('BAD end event recieved');
});
}).end();
答案 1 :(得分:0)
节点中的http模块适用于Server Sent Events,而大多数Node SSE的演示代码都使用它。但是你必须要小心一些陷阱。
我开始压缩了一下。解决方案是在每条数据消息的最后res.flush()
之后添加res.write()
。由于这是一个简单的修复,我会先尝试使用不同的模块进行重写。