我尝试使用HTML5 EventSourcing API https://developer.mozilla.org/de/docs/Web/API/EventSource将事件推送到我的客户端应用程序(javascript)。
通过一个简单的示例节点实现,它可以完美且按预期运行。示例代码:https://www.html5rocks.com/en/tutorials/eventsource/basics/
当我尝试将EventSourcing(或SSE)集成到基于hapi(当前使用的是最新的-18.1.0)的API端点中时,它不起作用。
const Stream = require('stream');
class ResponseStream extends Stream.PassThrough {
setCompressor (compressor) {
this._compressor = compressor;
}
}
const stream = new ResponseStream();
let data = 0;
setInterval(() => {
data++;
stream.write('event: message\n');
stream.write('data:' + data + '\n\n');
console.log('write data...', data);
// stream.end();
}, 1000);
return h
.response(stream)
.type('text/event-stream')
.header('Connection', 'keep-alive')
.header('Cache-Control', 'no-cache')
我已经搜索过,并且似乎从hapi 17.x开始,他们公开了压缩器<https://github.com/hapijs/hapi/issues/3658>的flush方法的部分功能。 但是它仍然不起作用。
它们发送消息的唯一方法是在发送数据后取消注释stream.end()行。问题显然是,如果我关闭流:/,我将无法发送更多数据。
如果我杀死服务器(使用stream.end()行注释),则数据将以“单一传输”的形式传输到客户端。我认为问题仍然存在于gzip缓冲中,即使在刷新流时也是如此。
在hapi github中有一些代码示例,但是我没有使用hapi 17或18(所有示例都在hapi = <16的情况下):/
有人知道如何解决该问题,或者有一个具有最新功能的有效EventSource示例?我将不胜感激任何帮助或建议。
以下文章中的解决方案确实有效,但我在api端点前面也有一个nginx反向代理,看来主要的问题不是我的代码,而是nginx缓冲了事件源消息。 为避免此类问题,请在您的hapi中添加: X-Accel-Buffering:no; ,它可以完美运行
答案 0 :(得分:0)
好吧,我刚刚使用Hapi 18.1.0进行了测试,并设法创建了一个有效的示例。
这是我的处理程序代码:
handler: async (request, h) => {
class ResponseStream extends Stream.PassThrough {
setCompressor(compressor) {
this._compressor = compressor;
}
}
const stream = new ResponseStream();
let data = 0;
setInterval(() => {
data++;
stream.write('event: message\n');
stream.write('data:' + data + '\n\n');
console.log('write data...', data);
stream._compressor.flush();
}, 1000);
return h.response(stream)
.type('text/event-stream')
}
这是要测试的客户端代码
var evtSource = new EventSource("http://localhost/");
evtSource.onmessage = function(e) {
console.log("Data", + e.data);
};
evtSource.onerror = function(e) {
console.log("EventSource failed.", e);
};
这些是我找到工作示例方法的资源
https://github.com/hapijs/hapi/blob/70f777bd2fbe6e2462847f05ee10a7206571e280/test/transmit.js#L1816
https://github.com/hapijs/hapi/issues/3599#issuecomment-485190525