没有stream.end()

时间:2019-06-16 21:29:26

标签: hapijs eventsource

尝试存档:

我尝试使用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>的flush方法的部分功能。 但是它仍然不起作用。

它们发送消息的唯一方法是在发送数据后取消注释stream.end()行。问题显然是,如果我关闭流:/,我将无法发送更多数据。

如果我杀死服务器(使用stream.end()行注释),则数据将以“单一传输”的形式传输到客户端。我认为问题仍然存在于gzip缓冲中,即使在刷新流时也是如此。

在hapi github中有一些代码示例,但是我没有使用hapi 17或18(所有示例都在hapi = <16的情况下):/

有人知道如何解决该问题,或者有一个具有最新功能的有效EventSource示例?我将不胜感激任何帮助或建议。

编辑-解决方案

以下文章中的解决方案确实有效,但我在api端点前面也有一个nginx反向代理,看来主要的问题不是我的代码,而是nginx缓冲了事件源消息。 为避免此类问题,请在您的hapi中添加: X-Accel-Buffering:no; ,它可以完美运行

1 个答案:

答案 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

These are my console results