Keep-Alive: Fazendo flush antes do término da execução, no controller do Symfony 2

No Symfony (1 e 2), a saída do controlador apenas é enviada após o processamento interno.

Para uma saída constante, em processos demorados, precisamos outra abordagem,

chamando o flush manualmente e seguindo o caminho Keep-Alive.

A necessidade

A CamelSpiderBundle possui um controller que executa a CamelSpider e isto pode demorar um pouco.

É necessário que exista uma saída informativa e uma negociação com o navegador para que não seja interrompida a exibição.

Solução: 

//….

    public function captureAction($id)
    {
        $response = new Response();
        $response->headers->set(‘Content-Encoding’, ‘chunked’);
        $response->headers->set(‘Transfer-Encoding’, ‘chunked’);
        $response->headers->set(‘Content-Type’, ‘text/html’);
        $response->headers->set(‘Connection’, ‘keep-alive’);
        $response->sendHeaders();
        flush();
        ob_flush();
        echo “<html><head><title>Capture</title></head><body><pre>”; 
        $this->get(‘camel_spider.launcher’)->checkUpdates($id);
         echo nnnn<b>Done</b>.”;
        echo “</pre></body></html>”;
        return $response;
    }
//…..
Você pode visualizar o arquivo completo aqui
Algumas informações relevantes:
Keep-Alive notes
Several people have asked me about the notes I sent around after theSan Jose conference regarding the Connection and Keep-Alive headers,upon which the NCSA, Spyglass, and a number of other implementationsof Keep-Alive were based.  Since I needed to rewrite them for HTTP/1.1anyway, here is the latest version, leaving out the discussion ofthe MGET and OPTIONS methods and concentrating on what seems to work.Please check them against your implementations and let me know ifthere are any problems......Roy======================================================================Keep-Alive Notes================In order for persistent connections to work properly in HTTP, thereneeds to be an easy mechanism whereby all parties to the HTTP communicationcan signal the desire for connection persistence and a willingness toabide by the stricter message requirements of HTTP/1.1.  These featurescan be implemented with HTTP/1.0, but cannot be used reliably with oldproxies and gateways until a new protocol version can be indicated.The primary mechanism is the Connection header field:    Connection  = "Connection" ":" 1#field-name      ; (see HTTP BNF)    [NOTE: field-names are case-insensitive]The Connection header is a list of header field names or keywordsthat apply only to the immediate connection (i.e., the connection withthe next closest client or server along a possible request/response chain).For example,   Connection: Keep-Alive, Fred   Keep-Alive: timeout=10, max=5Proxies are required to remove or rewrite (replace with their ownconnection options) the Connection header and any of the header fieldsnamed by the Connection header.  This prevents the problem of connectionoptions being propagated beyond the immediate connection.  If a name givenby the Connection header does not correspond to a separate header field(like Fred in the above example), then it is treated as a keyword tokenwithout any attributes.  This allows for a minimal syntax to provideconnection-based options without pre-restricting the syntax or numberof those options.The second mechanism is the Keep-Alive keyword/header field:   Keep-Alive  = "Keep-Alive" ":" 1#( token ["=" word ] )The presence of the Keep-Alive keyword in a Connection header signalsthat the sender wishes to maintain a persistent conne
ction.  The presenceof a Keep-Alive header field defines parameters for the persistence.So, the client can send    Connection: keep-aliveto indicate that it desires a multiple-request session, and the server responds with   Connection: keep-alive   Keep-Alive: max=20, timeout=10to indicate that the session is being kept alive for a maximum of20 requests and a per-request timeout of 10 seconds.  The Connection headerwith keep-alive keyword must be sent on all requests and responses thatwish to continue the persistence.  The client sends requests as normaland the server responds as normal, except that all messages containingan entity body must have an accurate content-length (or, if HTTP/1.1 isused by the recipient, a chunked transfer encoding). The persistent connection ends when either side closes the connection orafter the receipt of a response which lacks the Keep-Alive keyword. The server may close the connection immediately after responding to arequest without a Keep-Alive keyword.  A client can tell if theconnection will close by looking for a Keep-Alive in the response.The actual parameters of the Keep-Alive exchange are still unknown andopen for experimentation.  The initial idea of using "max" and "timeout"to indicate session-length preference (on requests) and actuals(on responses) is optional.  Another possibility is   Keep-Alive: state="Accept,Accept-Language,..."for indicating which header fields can be or have been stored as apersistent request state.  This would allow the server to decide whetheror not to be stateless in its request handling, and the amount of stateit is willing/able to retain, while at the same time allowing eachrequest to override the saved state with or without changing what is saved.The third mechanism is the chunked Transfer-Encoding which will beavailable in HTTP/1.1.   Transfer-Encoding  = "Transfer-Encoding" : 1#( token *(";" param))as in   Transfer-Encoding: chunkedThe chunked transfer encoding allows the message Entity-Body lengthto be determined dynamically as a sequence of data chunks prefixed bya chunk size, ended with a zero-size chunk, and followed by a footercontaining additional entity-header fields.   Chunky-Body = *( chunk )                  "0" CRLF                 footer                 CRLF    chunk       = chunk-size CRLF chunk-data CRLF    chunk-size  = hex-no-zero *hex    chunk-data  = chunk-size(OCTET)    footer      = *( Entity-Header )    hex         = "0" | hex-no-zero   hex-no-zero = "1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"               | "A"|"B"|"C"|"D"|"E"|"F"               | "a"|"b"|"c"|"d"|"e"|"f"Chunking the content makes the protocol output identical to normalbuffered writes, and thus is trivial to implement and very fast.In addition, it allows the server to append a dynamically generatedsignature to dynamically generated content -- a required feature forsome security applications.There are still other mechanisms which will be available for allowingmultiple requests/responses per message, such as the WRAPPED method andrestricted multipart types, but I won't be able to describe those untilI can find (or write) a working implementation. ...Roy T. Fielding    Department of Information & Computer Science    ([email protected])    University of California, Irvine, CA 92717-3425    fax:+1(714)824-4056    http://www.ics.uci.edu/~fielding/

Chunked transfer encoding

is a data transfer mechanism in version 1.1 of the Hypertext Transfer Protocol (HTTP) in which a web server serves content in a series of chunks. It uses the Transfer-Encoding HTTP response header in place of the Content-Length header, which the protocol would otherwise require. Because the Content-Length header is not used, the server does not need to know the length of the content before it starts transmitting a response to the client (usually a web browser). Web servers can begin transmitting responses with dynamically-generated content before knowing the total size of that content.

The size of each chunk is sent right before the chunk itself so that a client can tell when it has finished receiving data for that chunk. The data transfer is terminated by a final chunk of length zero.

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *