我正在尝试实现可读流的._read函数,当调用._read并且没有数据时会发生问题,文档说我可以推送(”)直到有更多数据出现,我应该只返回当流将永远不会有更多数据时为false.
https://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响应时,我的服务器将音频流传输给它.
什么是更聪明的方法呢?
最佳答案 因此,如果我正确地执行代码,您:
>收到请求,
>向远程端点发出您自己的请求并获取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);
});
});
});
现在,正如评论中所说,使用streams2,您不必管理您的流.对于0.10之前的节点版本,您必须收听“读取”,“数据”等事件,并使用较新的节点版本进行处理.此外,你甚至不需要它,溪流足够聪明,可以自己处理背压.