我正在尝试从express.js端点发送SSE text/event-stream
响应。我的路由处理程序如下:
function openSSE(req, res) {
res.writeHead(200, {
'Content-Type': 'text/event-stream; charset=UTF-8',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'Transfer-Encoding': 'chunked'
});
// support the polyfill
if (req.headers['x-requested-with'] == 'XMLHttpRequest') {
res.xhr = null;
}
res.write(':' + Array(2049).join('\t') + '\n'); //2kb padding for IE
res.write('id: '+ lastID +'\n');
res.write('retry: 2000\n');
res.write('data: cool connection\n\n');
console.log("connection added");
connections.push(res);
}
后来我打电话给:
function sendSSE(res, message){
res.write(message);
if (res.hasOwnProperty('xhr')) {
clearTimeout(res.xhr);
res.xhr = setTimeout(function () {
res.end();
removeConnection(res);
}, 250);
}
}
我的浏览器发出并保留请求:
没有任何响应被推送到浏览器。我的事件都没有被解雇。如果我杀了express.js服务器。响应突然消失,每个事件立即触及浏览器。
如果我更新我的代码以在res.end()
行之后添加res.write(message)
它会正确刷新流,但它会回退到事件轮询并且不会流式传输响应。
我已经尝试过将填充添加到响应的头部了
res.write(':' + Array(2049).join('\t') + '\n');
正如我从其他SO帖子中看到的那样,可以触发浏览器来消除响应。
我怀疑这是express.js的一个问题,因为我以前一直使用此代码与节点本机http
服务器,它正常工作。所以我想知道是否有某种方法可以绕过快递包装的响应对象。
答案 0 :(得分:1)
这是我在项目中使用的代码。
服务器端:
router.get('/listen', function (req, res) {
res.header('transfer-encoding', 'chunked');
res.set('Content-Type', 'text/json');
var callback = function (data) {
console.log('data');
res.write(JSON.stringify(data));
};
//Event listener which calls calback.
dbdriver.listener.on(name, callback);
res.socket.on('end', function () {
//Removes the listener on socket end
dbdriver.listener.removeListener(name, callback);
});
});
客户方:
xhr = new XMLHttpRequest();
xhr.open("GET", '/listen', true);
xhr.onprogress = function () {
//responseText contains ALL the data received
console.log("PROGRESS:", xhr.responseText)
};
xhr.send();
答案 1 :(得分:1)
我也在为此而苦苦挣扎,因此在浏览和阅读后,我通过为响应对象设置了额外的标题来解决了这个问题:
res.writeHead(200, {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache",
"Content-Encoding": "none"
});
长话短说,当EventSource
与服务器进行协商时,它正在发送Accept-Encoding: gzip, deflate, br
头,这使express
用Content-Encoding: gzip
头进行响应。因此,针对此问题有两种解决方案,一种是在响应中添加Content-Encoding: none
标头,第二种是(gzip)压缩响应。