readable.on('end',...) 永远不会被触发



我正在尝试将一些音频流式传输到我的服务器,然后将其流式传输给用户指定的服务,用户将向我提供someHostName,它有时不支持这种类型的请求。

我的问题是,当发生这种情况时,clientRequest.on('end',..)从未被激发,我认为这是因为它被管道传输到someHostReq,而当someHostName"错误"时,它就会变得一团糟。

我的问题是:

即使流clientRequest管道有问题,我是否仍然可以激发clientRequest.on('end',..)

如果不是:我如何"立即"检测出someHostReq出现了问题?someHostReq.on('error')只有一段时间后才会启动。

代码:

    someHostName = 'somexample.com'
    function checkIfPaused(request){//every 1 second check .isPaused
        console.log(request.isPaused()+'>>>>');
        setTimeout(function(){checkIfPaused(request)},1000);
    }
    router.post('/', function (clientRequest, clientResponse) {
        clientRequest.on('data', function (chunk) {
            console.log('pushing data');
        });
        clientRequest.on('end', function () {//when done streaming audio
            console.log('im at the end');
        }); //end clientRequest.on('end',)
        options = {
            hostname: someHostName, method: 'POST', headers: {'Transfer-Encoding': 'chunked'}
        };
        var someHostReq = http.request(options, function(res){
            var data = ''
            someHostReq.on('data',function(chunk){data+=chunk;});
            someHostReq.on('end',function(){
                console.log('someHostReq.end is called');
            });
        });
        clientRequest.pipe(someHostReq);
        checkIfPaused(clientRequest);
    });

输出:

如果主机名正确:

    pushing data
    .
    .
    pushing data
    false>>>
    pushing data
    .
    .
    pushing data
    pushing data
    false>>>
    pushing data
    .
    .
    pushing data
    console.log('im at the end');
    true>>>
    //continues to be true, that's fine

在主机名错误的情况下:

    pushing data
    .
    .
    pushing data
    false>>>>
    pushing data
    .
    .
    pushing data
    pushing data
    false>>>>
    pushing data
    .
    .
    pushing data
    true>>>>
    true>>>>
    true>>>>
    //it stays true and clientRequest.on('end') is never called
    //even tho the client is still streaming data, no more "pushing data" appears

如果你认为我的问题是重复的:

  • 与此不同:node.js http.request事件流-我的END事件去了哪里,OP只是进行GET而不是POST

  • 与此不同:node.js中的http.createserver;不起作用,流处于暂停模式,因为没有发生以下任何情况:

您可以通过执行以下任一操作切换到流动模式:

添加"data"事件处理程序以侦听数据。

调用resume()方法以显式打开流。

调用pipe()方法将数据发送到可写表。

来源:https://nodejs.org/api/stream.html#stream_class_stream_readable

  • 这与以下不同:来自http请求的Node.js响应没有调用';end';不包括';数据';事件,他只是忘记添加.on('data',..)

在主机名错误的情况下,缓冲区的行为似乎有问题,如果目标流缓冲区已满(因为someHost没有获得发送的数据块),管道将不会继续读取源流,因为管道会自动管理流。由于管道未读取原始流,您永远无法到达"结束"事件。

是否仍然可以在('end',..)上激发clientRequest.on即使流clientRequest管道到有问题它

除非数据被完全消耗掉,否则"end"事件不会激发。要用暂停的流激发"end",您需要调用resume()(首先从错误的主机名中取消绑定,否则您将再次陷入缓冲区阻塞),以将蒸汽再次设置为flowMode或read()

但是,如何检测我什么时候应该做上述任何一项?

someHostReq.on('error')是一个自然的地方,但如果它需要很长时间才能启动:

首先尝试设置一个较低的超时请求(小于someHostReq.on('error')触发所需的时间,这对您来说似乎太长了)request.setTimeout(timeout[, callback]),并检查在正确的主机名时它是否没有失败。如果有效,只需使用callbacktimeout事件来检测服务器超时的时间,并使用上面的一种技术到达最后。

如果超时解决方案失败或不符合您的要求,您必须使用clientRequest.on('data')clientRequest.on('end')和/或clienteRequest.isPaused中的标志来猜测何时被缓冲区卡住。当你认为你被卡住了,只需应用上面的一种技术就可以到达流的末尾。幸运的是,与等待someHostReq.on('error')相比,检测缓冲区卡住所需的时间更少(可能可以找到两个未到达data'request.isPaused() = true事件来确定您是否被卡住)。

如何检测someHostReq出现错误"立即"?someHostReq.on('error')除了在一段时间。

触发时会触发错误。你不能"立即"检测到它。?为什么不在管道流之前发送一个证明信标请求来检查支持?某种:

"检查用户指定的服务…"If OK->将用户请求流管道传输到服务OR FAIL->通知用户错误的服务。

相关内容

  • 没有找到相关文章

最新更新