Bu örneğimizde symfony uygulamamızdan gelen sonucu, twig şablonunda görüntüleyeceğiz ama gelen sonuç bir tane olmayacak. Birden fazla yayın akışı şeklinde gelen sonuçları, gelir gelmez hemen görüntüleyeceğiz. Bunun için symfony içindeki StreamedResponse class'ını kullanacağız.


Controller


namespace Football\FrontendBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;

/**
* @Route("", service="football_frontend.controller.default")
*/
class DefaultController
{
private $templating;

public function __construct(
EngineInterface $templating
) {
$this->templating = $templating;
}

/**
* @Method({"GET"})
* @Route("")
*
* @return Response
*/
public function indexAction()
{
return $this->templating->renderResponse('FootballFrontendBundle:Default:index.html.twig');
}

/**
* @param Request $request
*
* @Method({"GET"})
* @Route("/ajax", name="default_ajax")
*
* @return Response
*/
public function ajaxAction(Request $request)
{
if (!$request->isXmlHttpRequest()) {
throw new BadRequestHttpException('AJAX request expected.');
}

$response = new StreamedResponse();
$response->setCallback(function () {
$repeat = 4;
for ($i = 1; $i < $repeat; ++$i) {
echo 'Line '.$i;

ob_flush();
flush();

if ($i < ($repeat - 1)) {
sleep(2);
}
}
});

return $response;
}
}

services:
football_frontend.controller.default:
class: Football\FrontendBundle\Controller\DefaultController
arguments:
- '@templating'

Twig şablonu


{% extends '::base.html.twig' %}

{% block body %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
$(document).ready(function () {
$('button').click(function () {
var lastResponseLength = false;

$('#stream-started').show();
$('#stream-output').empty();
$('#stream-output').show();

setTimeout(startStreaming(lastResponseLength), 1500);
});

function startStreaming(lastResponseLength) {
xhr = new XMLHttpRequest();
xhr.open('GET', '{{ (path('default_ajax')) }}', true);
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');

xhr.onprogress = function(e) {
var response = e.currentTarget.response;
var output = lastResponseLength === false
? response
: response.substring(lastResponseLength);

lastResponseLength = response.length;

$('#stream-output').append('<p>'+output+'</p>');
};

xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
$('#stream-output').append('<p>Completed!</p>');
}
};

xhr.send();
}
});
</script>

<h3>StreamedResponse!</h3>
<hr />
<button id="test">Start streaming</button>
<p id="stream-started" style="display: none;">Here comes the stream ...</p>
<code id="stream-output" style="display: none;"></code>
<hr />
{% endblock %}

Test


Uygulamanızın ana sayfasına gidin ve "Start streaming" butonunu tıklayın. Gelen cevapların tek tek görüntülendiğini göreceksiniz. Aşağıdaki resim sadece gösteri amaçlıdır yani siz sadece bir tane çıktı göreceksiniz.