0

After receiving an AJAX request, I want to give feedback to the user before the PHP script finishes, because it takes long.

I thought that the send() method of the yii\web\Response object was made for that, so I tried the following inside the controller action:

Yii::$app->response->format = Response::FORMAT_JSON;
Yii::$app->response->data = [ 'success' => $someData ];
Yii::$app->response->send();

// code that takes long
sleep(5);

The response is sent, but after sleeping for 5 seconds.

Same luck with:

ob_start();
echo json_encode([ 'success' => $someData ]);
header('Connection: close');
header('Content-Type: application/json');
header('Content-Length: '.ob_get_length());
ob_end_flush();
flush();

// code that takes long
sleep(5);

I didn't have any confidence in this last code working inside a controller action, but I had it in the first one... what am I missing?

EDIT: I'm using nginx + PHP_FPM

David
  • 6,695
  • 3
  • 29
  • 46

2 Answers2

0

I think what you searching for is the long polling

Here is fine working example for long polling implementation on PHP+jQuery

https://github.com/panique/php-long-polling

And here is related topic with deep explanation of different technologies in that area (including long polling) -- What are Long-Polling, Websockets, Server-Sent Events (SSE) and Comet?

Also you can take a look at this video tutorial

https://www.screenr.com/SNH

Community
  • 1
  • 1
oakymax
  • 1,454
  • 1
  • 14
  • 21
  • Thank you for the answer. I'm not quite sure that's what I'm looking for. I need some time to dig into the topic, but I surely will come back. – David Jul 12 '16 at 21:33
  • 1
    I'm here in 2021 to say that this "long polling" git link is literally just a loop of AJAX... It just requests data again and again. And the PHP script is just set up in a way that it only "ends" and outputs a response when something has changed... This is definitely NOT doing anything similar to a websocket or push notification. – Nerdi.org Nov 20 '21 at 20:28
0

PHP_FPM has fastcgi-finish-request() available:

This function flushes all response data to the client and finishes the request. This allows for time consuming tasks to be performed without leaving the connection to the client open.

Yii::$app->response->format = Response::FORMAT_JSON;
Yii::$app->response->data = [ 'success' => $someData ];
Yii::$app->response->send();

fastcgi-finish-request();

// code that takes long
sleep(5);
David
  • 6,695
  • 3
  • 29
  • 46