简体   繁体   English

如何使用 Proxygen 和 Folly 发送 HTTP 分块响应以模拟视频流?

[英]How to send HTTP chunked response to emulate a video stream using Proxygen and Folly?

I am writing a HTTP video streaming server based on Facebooks Proxygen.我正在编写一个基于 Facebooks Proxygen 的 HTTP 视频流服务器。 There is no seeking planned.没有寻求计划。 Using the proxygen::ResponseBuilder I am abled to send chunks of a webm encoded video as HTTP response, ie chunked transfer encoding is working.使用proxygen::ResponseBuilder我能够将 webm 编码的视频块作为 HTTP 响应发送,即分块传输编码正在工作。 My problem is, that Proxygen waits for proxygen::ResponseBuilder::sendWithEOM() before it even sends the response headers.我的问题是,Proxygen 甚至在发送响应标头之前等待proxygen::ResponseBuilder::sendWithEOM() I would like it to actually send the data asap after each call to proxygen::ResponseBuilder::send() .我希望它在每次调用proxygen::ResponseBuilder::send()后尽快实际发送数据。

I tried to run the ResponseBuilder calls from a lambda executed from the EventBaseThread using evb->runInLoop() and evb->runInEventBaseThread()我尝试使用evb->runInLoop()evb->runInEventBaseThread()从 EventBaseThread 执行的 lambda 中运行 ResponseBuilder 调用

using namespace folly;
using namespace proxygen;

std::thread t([&](){
    EventBase* evb = EventBaseManager::get()->getExistingEventBase();    
    // send headers ...
    while ( chunks avail. ) {
        //...
        evb->runInLoop([&](){
            ResponseBuilder(downstream_)
                     .body(std::move(chunk))
                     .send();
        });
        //... 
    }
    // sendWithEOM ...
});
t.detach();

This code is called from the onRequest() method of my RequestHandler .这段代码是从我的RequestHandleronRequest()方法调用的。 I tried to call ResponseBuilder::send() without wrapping it into evb->runInLoop() , but Proxygen v0.25.0 with Folly v0.42.0 is prohibiting calls to ResponseBuilder::send() from another thread using an assert.我试图调用ResponseBuilder::send()而不将其包装到evb->runInLoop() ,但是带有 Folly v0.42.0 的 Proxygen v0.25.0 禁止使用断言从另一个线程调用ResponseBuilder::send() I removed this assert from here: https://github.com/facebook/folly/blob/v0.42.0/folly/io/async/EventBase.cpp#L491 .我从这里删除了这个断言: https : //github.com/facebook/folly/blob/v0.42.0/folly/io/async/EventBase.cpp#L491

Now the emulated streaming is working, but it's crashing, if there are parallel requests.现在模拟流正在工作,但如果有并行请求,它就会崩溃。 I guess it was not meant to be used like this, that's what the assert is for.我想它不应该像这样使用,这就是断言的用途。 But maybe anyone knows how to use the Proxygen infrastructure properly for my usecase?但也许有人知道如何为我的用例正确使用 Proxygen 基础设施?

That's got the same issue.那有同样的问题。 I got it working with something like this.我让它与这样的事情一起工作。

folly::EventBase* eventBase = folly::EventBaseManager::get()->getExistingEventBase();
thread t([&, eventBase]() {
    while( chunks exist ) {
        auto chunk = getChunk();    
        eventBase->runInEventBaseThread([&, chunk=chunk]() mutable {
            ResponseBuilder(downstream_).body(move(chunk)).send();
        });
    }
});
// sendWithEOM ...
t.detach();
using namespace folly;
using namespace proxygen;

//Get Event Base in worker thread and pass it to new thread. If you call this inside new thread then you won't get worker thread's event base.
EventBase* evb = EventBaseManager::get()->getExistingEventBase();   
std::thread t([&, evb](){

// send headers ...
while ( chunks avail. ) {
    //...
    evb->runInLoop([&](){
        ResponseBuilder(downstream_)
                 .body(std::move(chunk))
                 .send();
    });
    //... 
}
// sendWithEOM ...
});
t.detach();

So no need to comment assertion in EventBase source.所以不需要在 EventBase 源中注释断言。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM