【问题标题】:Response returned only after kernel.terminate event响应仅在 kernel.terminate 事件之后返回
【发布时间】:2014-07-06 08:31:35
【问题描述】:

我对@9​​87654321@ 的理解是它响应返回给客户端之后触发。

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

我在配置中有以下内容:

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 标头有关。如果我生成它,响应会正确返回。

// 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);

【问题讨论】:

  • 这是 Symfony 中的错误还是有目的?

标签: symfony nginx fastcgi


【解决方案1】:

这个问题被证明是我的设置(Nginx、PHP-FCGI、Symfony)非常具体的问题。

有几个问题导致了这个问题:

  1. Symfony 不包含 Content-LengthConnection: close 标头
  2. PHP-FCGI 不支持fastcgi_finish_request 函数
  3. Nginx 缓冲来自 PHP-FCGI 的响应,因为 Gzip 已开启

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

解决这个问题的另一种方法是关闭 Nginx 上的 Gzip,但这对我来说并不是一个真正的选择。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-22
  • 2011-08-11
  • 2017-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多