12

I am trying this example from the doc: Streaming a Response in Symfony2.

/**
 * @param Request $request
 * @return Response $render
 * @Route("/streamedResponse", name="streamed_response")
 * @Template("AcmeTestBundle::streamedResponse.html.twig")
 */
public function streamedResponseAction(Request $request)
{
    $response = new StreamedResponse();
    $response->setCallback(function () {
        echo 'Hello World';
        flush();
        sleep(3);
        echo 'Hello World';
        flush();
    });

    return $response;

}

This outputs everything at the same time. Have I done something wrong?

Lorenzo Polidori
  • 10,332
  • 10
  • 51
  • 60
Mick
  • 30,759
  • 16
  • 111
  • 130
  • 1
    try `ob_flush()` before `flush()` – mask8 Sep 12 '12 at 03:39
  • I tried in case but this does not work as there is no `ob_start()`. It does not work with both `ob_start` and `ob_flush` either. – Mick Sep 12 '12 at 03:41
  • 1
    I thought you might have output_buffering in php.ini set to 4096 which some default php.ini have. – mask8 Sep 12 '12 at 03:47
  • 2
    in my case, `ob_flush()` did fix the issue. how are you testing it? you know browser won't show the second Hello World 3 seconds after the first one right? You need to test it via telnet or netcat or something – mask8 Sep 12 '12 at 04:09
  • Ok! Can you post a reply and I'll accept it. Would you mind adding some info about telnet or the way you use it? That would be awesome. Thanks @mask8 – Mick Sep 12 '12 at 05:11

1 Answers1

23

I tried adding ob_flush() and it seems to be working. Here is my code:

public function streamedAction()
{
    $response = new StreamedResponse();
    $response->setCallback(function () {
        echo 'Hello World';
        ob_flush();
        flush();
        sleep(3);
        echo 'Hello World';
        ob_flush();
        flush();
    });

    return $response;
}

This returns chunked transfer encoding header with chunked data. Here is output of results:

$ telnet localhost 80
Trying ::1...
Connected to localhost.
Escape character is '^]'.
GET /app_dev.php/streamed HTTP/1.1
Host: symfony21.localdomain

HTTP/1.1 200 OK
Date: Wed, 12 Sep 2012 05:34:12 GMT
Server: Apache/2.2.17 (Unix) DAV/2 mod_ssl/2.2.17 OpenSSL/0.9.8o
cache-control: no-cache, private
x-debug-token: 50501eda7d437
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8

b
Hello World
b
Hello World
0

Connection closed by foreign host.

If you see this response in browser, it will display "HelloWorldHelloWorld" after about 3 seconds loading as browser will wait until all chunked data is received as Content-Type is text/*, but when you see the network stream, it is actually doing streaming by sending chunked data.

Lorenzo Polidori
  • 10,332
  • 10
  • 51
  • 60
mask8
  • 3,560
  • 25
  • 34
  • @mask8 Do you know how to write functional tests for streamed content using the Symfony test client? I asked a question about that: [How to retrieve a streamed response with Symfony test client](http://stackoverflow.com/q/15734677/885464) – Lorenzo Polidori Apr 10 '13 at 08:00