【问题标题】:what should I use instead of readableStream.push('')我应该用什么代替 readableStream.push('')
【发布时间】:2015-12-29 22:22:21
【问题描述】:

我正在尝试实现可读流的._read 函数,当调用._read 并且没有数据时会出现问题,文档说我可以push('') 直到有更多数据出现,我当流永远不会有更多数据时,应该只return falsehttps://nodejs.org/api/stream.html#stream_readable_read_size_1

但它也表示,如果我需要这样做,那么我的设计就出现了严重错误。 https://nodejs.org/api/stream.html#stream_stream_push

但我找不到替代方案。

代码:

    var http = require('http');
    var https = require('https');
    var Readable = require('stream').Readable;
    var router = require('express').Router();
    var buffer = [];

    router.post('/', function(clientRequest, clientResponse) {
        var delayedMSStream = new Readable;
        delayedMSStream._read = function() {
            var a=buffer.shift();
            if(typeof a === 'undefined'){
                this.push('');
                return true;
            }
            else {
                this.push(a);
                if(a===null) {
                    return false;
                }
                return true;
            }
        };
        //I need to get a url from example.com
        https.request({hostname:'example.com'}, function(exampleResponse){
            data='';
            exampleResponse.on('data',function(chunk){data+=chunk});
            exampleResponse.on('end',function(){
                var MSRequestOptions = {hostname: data, method: 'POST'};
                var MSRequest = https.request(MSRequestOptions, function(MSResponse){
                    MSResponse.on('end', function () {
                            console.log("MSResponse.on(end)");//>>>
                    });//end MSResponse.on(end)
                }); //end MSRequest
                delayedMSStream.pipe(MSRequest);
            });
        });

        clientRequest.on('data', function (chunk) {
            buffer.push(chunk);
        });

        clientRequest.on('end', function () {//when done streaming audio
            buffer.push(null);
        }); 
    });//end router.post('/')

解释: 客户端向我的服务器发送一个 POST 请求流式音频,我的服务器从example.com 请求一个 url,当example.com 响应该 url 时,我的服务器将音频流式传输给它。

什么是更聪明的方法?

【问题讨论】:

  • 什么是buffer?你从哪里得到的?
  • clientRequest.on('data',function(chunk){ buffer.push(chunk); });它在代码中^
  • 不,我没看到 - 你得到一个 chunk 并将其推送到 缓冲区。但我看不出你在哪里定义了缓冲区。
  • 哦,对不起,我误解了你的评论,刚刚修复它,var buffer=[];
  • 在这种情况下,我认为您可能误读了文档的“推送返回错误”部分。它是您的 _read 函数中的 let result = this.push(chunk);。如果结果为假,则流应停止发送数据一段时间(意味着另一端无法接收更多数据)。但这是一种内部方法/检查,仅适用于旧流,不适用于流 2。

标签: node.js stream


【解决方案1】:

所以如果我理解正确的代码,你:

  • 接收请求,
  • 向远程端点发出您自己的请求并获取 URL
  • 向该 URL 发出新请求并将其通过管道传输到原始响应。

除了你的方法之外,还有其他方法可以做到这一点,如果你稍微改进一下命名,即使你的方法在我看来也会更干净。此外,将庞大的请求拆分为责任范围较小的几个函数可能会有所帮助。

我会这样设置端点:

let http = require('http');
let https = require('https');
let Readable = require('stream').Readable;
let router = require('express').Router();
let buffer = [];

/**
 * Gets some data from a remote host. Calls back when done.
 * We cannot pipe this directly into your stream chain as we need the complete data to get the end result.
 */
function getHostname(cb) {

  https.request({

    hostname: 'example.com'
  }, function(response) {

    let data = '';
    response.on('error', err => cb(err)); // shortened for brewity
    response.on('data', function(chunk) {

        data = data + chunk;
    });
    response.on('end', function() {

      // we're done here.
      cb(null, data.toString());
    });
  });
}

router.post('/', function(request, response) {

  // first let's get that url.
  getHostname(function(err, hostname) {

    if (err) { return response.status(500).end(); } 

    // now make that other request which we can stream.
    https.request({

      hostname: hostname,
      method: 'POST'
    }, function(dataStream) {

        dataStream.pipe(response);
    });
  });
});

现在,正如 cmets 中所说,使用streams2,您不必管理您的流。使用 0.10 之前的节点版本,您必须收听“读取”、“数据”等事件,使用较新的节点版本,它会被处理。此外,这里甚至不需要它,流足够智能,可以自行处理背压。

【讨论】:

    猜你喜欢
    • 2014-05-29
    • 1970-01-01
    • 2010-11-05
    • 2010-12-06
    • 2012-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多