首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Readable.on(“结束”,……)永远不会被解雇

Readable.on(“结束”,……)永远不会被解雇
EN

Stack Overflow用户
提问于 2015-12-31 02:10:55
回答 1查看 3K关注 0票数 7

我试图将一些音频流到我的服务器,然后将其流到用户指定的服务中,用户将为我提供someHostName,有时可能不支持这种类型的请求。

我的问题是,当它发生时,clientRequest.on('end',..)从未被触发,我认为这是因为它被输送到someHostReq,当someHostName是“错误的”时,它就会变得一团糟。

我的问题是:

不管怎么说,即使流clientRequest.on('end',..)的管道有问题,我仍然可以让clientRequest被触发吗?

如果不是:我如何发现someHostReq“立即”发生了一些错误?除非过了一段时间,否则someHostReq.on('error')不会启动。

代码:

代码语言:javascript
复制
    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);
    });

产出:

在正确的主机名的情况下:

代码语言:javascript
复制
    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

在主机名错误的情况下:

代码语言:javascript
复制
    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

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

您可以通过执行以下任何操作切换到流模式: 添加一个“数据”事件处理程序来侦听数据。 调用简历()方法显式地打开流。 调用管道()方法将数据发送到Writable。

来源:readable

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-01-11 09:35:57

在主机名错误的情况下,如果目标流缓冲区已满(因为someHost没有收到发送的数据块),则该管道将不会继续读取源流,因为管道会自动管理流。由于管道没有读取原始流,所以永远不会到达“end”事件。

我是否仍然可以拥有clientRequest.on('end',.)即使在流clientRequest管道有问题的时候也会触发吗?

除非数据被完全消耗,否则“end”事件不会触发。要用暂停的流触发“end”,您需要调用resume() (首先从错误的主机名中解压,否则会再次陷入缓冲区卡住),将蒸汽再次设置为flowMode或read()到末尾。

但是如何检测我什么时候应该做上述任何一件事呢?

SomeHostReq.on(“错误”)是很自然的地方,但如果启动时间太长:

首先,尝试设置一个低超时请求(小于someHostReq.on('error')触发所需的时间(似乎对您来说时间太长),并检查它在正确的主机名时是否失败。如果有效,只需使用callbacktimeout事件来检测服务器timeOut的时间,并使用上述技术之一到达终点。

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

如何检测到someHostReq“立即”发生了一些错误?SomeHostReq.on(“错误”)只有在一段时间后才会启动。

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

“用户指定的阻塞服务.”If OK ->管道用户请求流服务OR失败->通知用户错误的服务。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34540095

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档