没有 stream.end() hapi 18 eventsourcing 无法工作
hapi 18 eventsourcing not working without stream.end()
尝试存档:
我尝试使用 HTML5 EventSourcing API https://developer.mozilla.org/de/docs/Web/API/EventSource 将事件推送到我的客户端应用程序 (javascript)。
使用纯节点 http:
的工作示例代码
通过一个简单的示例节点实现,它可以完美地按预期工作。示例代码: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 > 部分功能的冲洗方法。
但是还是不行。
他们发送消息的唯一方法是在发送数据后取消注释 stream.end() 行。问题显然是,如果我关闭流,我将无法发送更多数据:/.
如果我终止服务器(注释 stream.end() 行),数据将在“单次传输”中传输到客户端。我认为即使在刷新流时问题仍然存在于 gzip 缓冲中。
hapi github 中有一些代码示例,但我 none 使用 hapi 17 或 18(所有示例中 hapi =< 16) :/
有人知道如何解决这个问题或有最新 hapi 的有效 EventSource 示例吗?如果有任何帮助或建议,我将不胜感激。
编辑 - 解决方案
下面 post 的解决方案确实有效,但我的 api 端点前面还有一个 nginx 反向代理,看来主要问题不是我的代码,而是 nginx 有还缓冲了事件源消息。
为避免此类问题,请在您的 hapi 中添加:X-Accel-Buffering: no; 并且它可以正常工作
好吧,我刚刚使用 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
尝试存档:
我尝试使用 HTML5 EventSourcing API https://developer.mozilla.org/de/docs/Web/API/EventSource 将事件推送到我的客户端应用程序 (javascript)。
使用纯节点 http:
的工作示例代码通过一个简单的示例节点实现,它可以完美地按预期工作。示例代码: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 > 部分功能的冲洗方法。 但是还是不行。
他们发送消息的唯一方法是在发送数据后取消注释 stream.end() 行。问题显然是,如果我关闭流,我将无法发送更多数据:/.
如果我终止服务器(注释 stream.end() 行),数据将在“单次传输”中传输到客户端。我认为即使在刷新流时问题仍然存在于 gzip 缓冲中。
hapi github 中有一些代码示例,但我 none 使用 hapi 17 或 18(所有示例中 hapi =< 16) :/
有人知道如何解决这个问题或有最新 hapi 的有效 EventSource 示例吗?如果有任何帮助或建议,我将不胜感激。
编辑 - 解决方案
下面 post 的解决方案确实有效,但我的 api 端点前面还有一个 nginx 反向代理,看来主要问题不是我的代码,而是 nginx 有还缓冲了事件源消息。 为避免此类问题,请在您的 hapi 中添加:X-Accel-Buffering: no; 并且它可以正常工作
好吧,我刚刚使用 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