繁体   English   中英

如何使用StreamedResponse在Symfony2中呈现模板视图

[英]How do I use StreamedResponse to render template view in Symfony2

我正在尝试使用streamedResponse将进度输出到Symfony2中的索引页面。

下面的代码确实显示了我在api调用时的进度,但是我在实际视图中渲染流信息时遇到了问题。 现在它只是在页面顶部输出纯文本,然后在全部完成时呈现视图。

我不想返回最后一个数组并关闭函数,直到所有内容都被加载,但我输出进度时似乎无法获得常规的twig模板。

我尝试过使用渲染但似乎没有任何东西真正将视图文件输出到屏幕,除非我返回。

 public function indexAction($countryCode)
    {

    //anywhere from five to fifteen api calls are going to take place
    foreach ($Widgets as $Widget) {

        $response = new StreamedResponse();

        $curlerUrl = $Widget->getApiUrl()
            . '?action=returnWidgets'
            . '&data=' . urlencode(serialize(array(
                'countryCode' => $countryCode
            )));

        $requestStartTime = microtime(true);
        $curler = $this->get('curler')->curlAUrl($curlerUrl);
        $curlResult = json_decode($curler['body'], true);


        if(isset($curlResult['data'])){
           //do some processing on the data
        }

        $response->setCallback(function() use ($Widget, $executionTime) {
            flush();
            sleep(1);
            var_dump($Widget->getName());
            var_dump($executionTime);
            flush();
        });

        $response->send();
    } 
    //rest of indexAction with a return statement

    return array(
      //all the vars my template will need       
    );
}

此外,另一个重要的细节是,我正在努力渲染所有的树枝,似乎有一些有趣的问题。

据我了解,您只有一次机会从服务器(PHP / Twig)向浏览器输出内容,然后由JavaScript进行任何进一步更改(如更新进度条)。

我建议使用multi-cURL异步执行所有15个请求。 这有效地使总请求时间等于最慢的请求,因此您可以更快地为页面提供服务,并且可以消除对进度条的需求。

// Create the multiple cURL handle
$mh = curl_multi_init();
$handles = array();
$responses = array();

// Create and add the cURL handles to the $mh
foreach($widgets as $widget) {
    $ch = $curler->getHandle($widget->getURL()); // Code that returns a cURL handle
    $handles[] = $ch;
    curl_multi_add_handle($mh, $ch);
}

// Execute the requests
do {
    curl_multi_exec($mh, $running);
    curl_multi_select($mh);
} while ($running > 0);

// Get the request content
foreach($handles as $handle) {
    $responses[] = curl_multi_getcontent($handle);

    // Close the handles
    curl_close($handle);
}
curl_multi_close();

// Do something with the responses
// ...

理想情况下,这将是您的Curler服务的一种方法。

public function processHandles(array $widgets)
{
    // most of the above

    return $responses;
}

您可以实现setCallback方法中的所有逻辑,因此请考虑以下代码:

public function indexAction($countryCode)
{

    $Widgets = [];

    $response = new StreamedResponse();

    $curlerService = $this->get('curler');

    $response->setCallback(function() use ($Widgets, $curlerService, $countryCode) {

        foreach ($Widgets as $Widget) {

            $curlerUrl = $Widget->getApiUrl()
                . '?action=returnWidgets'
                . '&data=' . urlencode(serialize(array(
                    'countryCode' => $countryCode
                )));

            $requestStartTime = microtime(true);
            $curler = $curlerService->curlAUrl($curlerUrl);
            $curlResult = json_decode($curler['body'], true);


            if(isset($curlResult['data'])){
                //do some processing on the data
            }
            flush();
            sleep(1);
            var_dump($Widget->getName());
            var_dump( (microtime(true) - $requestStartTime) );
            flush();

        }

    });

    // Directly return the streamed response object
    return $response;

}

进一步阅读文章。

希望这有帮助

暂无
暂无

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

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