[英]Server-sent events with node.js http2 module - how should I use it with stream / pushStream?
我正在尝试实现一个每 500 毫秒发送大量数据(对象,而不是文件)的服务器。 经过一些阅读,服务器通过 http2 发送的事件似乎是最快的选择(由于 http2 是二进制协议,而 SSE 减少了流量开销)
在 http/1.1 上玩过SSE 之后,我一直在尝试在 http2 上做同样的事情。 我尝试使用stream和pushStream这样做,但没有成功。 但是,使用我用于 http/1.1 的相同方式似乎有效。
我的问题是 - 为什么使用流的服务器 1(见下文)不起作用,而服务器 2 似乎工作正常? 工作节点流时我错过了什么吗?
我正在使用节点v10.9.0
和 chrome 68.0.3440.106
我已阅读以下问题和帖子,但仍然无法解决此问题:
服务器 1 - 带有流的 http2(不工作 - 客户端没有获取事件。chrome 将请求描述为未完成的请求):
const fs = require('fs');
const http2 = require('http2');
const HTTPSoptions = {
key: fs.readFileSync('./cert/selfsigned.key'),
cert: fs.readFileSync('./cert/selfsigned.crt'),
};
const template = `
<!DOCTYPE html>
<html>
<body>
<script type="text/javascript">
const source = new EventSource('/sse/');
source.onmessage = function(e) {
document.body.innerHTML += e.data + '<br>';
};
</script>
</body>
</html>
`;
const server = http2.createSecureServer(HTTPSoptions);
server.on('stream', (stream, headers, flags) => {
if (stream.url === 'sse/') {
console.log(stream.respond);
stream.respond({
':status': 200,
'content-type': 'text/event-stream'
});
setInterval(() => stream ? res.write(`data: ${Math.random()}\n\n`) : '', 200);
}
});
server.on('request', (req, res) => {
if(req.url === '/') {
res.end(template);
}
});
server.listen(3001);
服务器 2 - 带有流的 http2(工作正常):
const fs = require('fs');
const http2 = require('http2');
const HTTPSoptions = {
key: fs.readFileSync('./cert/selfsigned.key'),
cert: fs.readFileSync('./cert/selfsigned.crt'),
};
const template = `
<!DOCTYPE html>
<html>
<body>
<script type="text/javascript">
const source = new EventSource('/sse/');
source.onmessage = function(e) {
document.body.innerHTML += e.data + '<br>';
};
</script>
</body>
</html>
`;
const server = http2.createSecureServer(HTTPSoptions);
server.on('request', (req, res) => {
req.socket.setKeepAlive(true);
if(req.url === '/sse/') {
res.writeHead(200, {
'Content-Type': 'text/event-stream', // <- Important headers
'Cache-Control': 'no-cache'
});
res.write('\n');
setInterval(() => res.write(`data: ${Math.random()}\n\n`), 200);
} else {
res.end(template);
}
});
server.listen(3001);
要获取 http2 流的请求路径,您必须查看:path
标头 ( docs ):
if (headers[':path'] === '/sse/') {
您还尝试使用res.write
,而res
应该是stream
。
这是一个基于“服务器 1”实现的工作处理函数:
server.on('stream', (stream, headers, flags) => {
if (headers[':path'] === '/sse/') {
stream.respond({
':status': 200,
'content-type': 'text/event-stream'
});
setInterval(() => stream.write(`data: ${Math.random()}\n\n`), 200);
}
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.