我对kernel.terminate
理解是在响应返回给客户端后触发。
在我的testing艰难中,这似乎并不是这样。 如果我把一个sleep(10)
放在kernel.terminate调用的函数中。 浏览器也等待10秒钟。 处理似乎在响应发送之前发生。
我有以下configuration:
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"; } }
UPDATE
这似乎与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);
这个问题原来是非常具体的我的设置(Nginx,PHP-FCGI,Symfony)。
造成这个问题的原因有很多:
Content-Length
也不包含Connection: close
标题 fastcgi_finish_request
功能 解决方案是从PHP-FCGI切换到PHP-FPM,以获得对fastcgi_finish_request
支持。 Symfony在执行内核终止逻辑之前内部调用它,从而明确地关闭连接。
解决这个问题的另一种方法是关闭Nginx上的Gzip,但这对我来说不是一个真正的选择。