仅在kernel.terminate事件之后返回响应 [英] Response returned only after kernel.terminate event

查看:100
本文介绍了仅在kernel.terminate事件之后返回响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对kernel.terminate的理解是,它会在响应返回给客户端之后触发.

My understanding of kernel.terminate is that it triggers after the response has been returned to the client.

在我艰难的测试中,情况似乎并非如此.如果我在kernel.terminate调用的函数中放入sleep(10).浏览器还会等待10秒.发送响应之前似乎正在处理.

In my testing tough, this does not appear to be the case. If I put a sleep(10) in the function that's called on kernel.terminate. the browser also waits for 10 seconds. The processing seems to be happening before the response is sent.

我在配置中有以下内容:

I have the following in config:

calendar:
    class: Acme\CalendarBundle\Service\CalendarService
    arguments: [ @odm.document_manager, @logger, @security.context, @event_dispatcher ]
    tags:
        - { name: kernel.event_subscriber }

我的订户类别:

class CalendarService implements EventSubscriberInterface
{
    public static function getSubscribedEvents()
    {
        return array(
            'kernel.terminate' => 'onKernelTerminate'
        );
    }

    public function onKernelTerminate()
    {
        sleep(10);
        echo "hello";
    }
}

更新

这似乎与Symfony没有发送Content-Length标头有关.如果我生成了该消息,则响应将正确返回.

This appears to be related to Symfony not sending a Content-Length header. If I generate that, the response return properly.

// app_dev.php
...
$kernel = new AppKernel('dev', true);
$kernel->loadClassCache();
$request = Request::createFromGlobals();
$response = $kernel->handle($request);

// --- START EDITS ---
$size = strlen($response->getContent());
$response->headers->set('Content-Length', $size);
$response->headers->set('Connection', 'close');
// ---- END EDITS ----

$response->send();
$kernel->terminate($request, $response);

推荐答案

事实证明,此问题非常特定于我的设置(Nginx,PHP-FCGI,Symfony).

This issue turned out to be very specific to my setup (Nginx, PHP-FCGI, Symfony).

导致问题的原因有很多:

There were a handful of issues in play that caused the issue:

  1. Symfony不包含Content-LengthConnection: close标头
  2. PHP-FCGI不支持fastcgi_finish_request函数
  3. 由于Gzip已打开,Nginx缓冲了来自PHP-FCGI的响应
  1. Symfony does not include a Content-Length nor Connection: close header
  2. PHP-FCGI does not support the fastcgi_finish_request function
  3. Nginx buffers the response from PHP-FCGI because Gzip is on

解决方案是从PHP-FCGI切换到PHP-FPM,以获得对fastcgi_finish_request的支持. Symfony在执行内核终止逻辑之前内部调用此方法,从而最终关闭连接.

The solution was to switch from PHP-FCGI to PHP-FPM in order to get support for fastcgi_finish_request. Symfony internally calls this before executing the kernel terminate logic thereby definitively closing the connection.

解决此问题的另一种方法是在Nginx上关闭Gzip,但这对我来说不是一个选择.

Another way to solve this would be to turn off Gzip on Nginx, but this wasn't really an option for me.

这篇关于仅在kernel.terminate事件之后返回响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆