如何使用Hapi将数据流式传输到浏览器?

时间:2015-07-03 16:22:00

标签: node.js request streaming hapijs

我尝试使用流来使用Hapi将数据发送到浏览器,但无法确定方法。具体来说,我正在使用request模块。根据文档,reply对象接受一个流,所以我尝试过:

reply(request.get('https://google.com'));

抛出错误。在文档中,它说流对象必须与streams2兼容,所以我尝试了:

reply(streams2(request.get('https://google.com')));

现在这不会引发服务器端错误,但在浏览器中请求永远不会加载(使用chrome)。

然后我尝试了这个:

var stream = request.get('https://google.com');
stream.on('data', data => console.log(data));
reply(streams2(stream));

在控制台中输出数据 ,所以我知道流不是问题,而是Hapi。我怎样才能在Hapi中流式传输?

2 个答案:

答案 0 :(得分:15)

尝试使用Readable.wrap

var Readable = require('stream').Readable;
...
function (request, reply) {

  var s = Request('http://www.google.com');
  reply(new Readable().wrap(s));
}

使用Node 0.10.x和hapi 8.x.x进行测试。在我的代码示例中,Request是节点请求模块,request是传入的hapi请求对象。

<强>更新

另一种可能的解决方案是从Request收听'response' event,然后使用reply http.IncomingMessage收听function (request, reply) { Request('http://www.google.com') .on('response', function (response) { reply(response); }); } ,这是一个正确的读取流。

.on('click')

这需要更少的步骤,并且还允许开发人员在传输之前将用户定义的属性附加到流。这在设置200以外的状态代码时非常有用。

答案 1 :(得分:0)

Happi 17.9.0

我找到了它!问题在于gzip压缩

要仅针对event-stream禁用它,您需要为Happi服务器提供下一个配置

const server = Hapi.server({
  port: 3000, 
  ...
  mime:{
    override:{
      'text/event-stream':{
        compressible: false
      }
    }
  }
});

在处理程序中,我使用axios是因为它支持新的流2协议

async function handler(req, h) {
    const response = await axios({
        url: `http://some/url`,
        headers: req.headers,
        responseType: 'stream'
    });

    return response.data.on('data',function (chunk) {
        console.log(chunk.toString());
    })

    /* Another option with h2o2, not fully checked */
    // return h.proxy({
    //     passThrough:true,
    //     localStatePassThrough:true,
    //     uri:`http://some/url`
    // });
};