I have a PHP script that import large data from csv files with validations.
For that I need to show progress to the user. I have used Event Streaming for that.
When I echo something,I want it to be transferred to client one by one instead of server sent whole output in bulk.
I had already played around with ob_start(),ob_implicit_flush() & ob_flush(),but they didn’t work.
My script is working perfect on another server.
Below server configurations are given:
代码未按要求响应的服务器配置,即
OS: Linux PHP Version 5.4.36-0+deb7u3 Server API: CGI/FastCGI Memory_limit: 128M output_buffering: no value
正如我所说,代码在另一台具有几乎相同配置的服务器上正常工作,即
OS: Linux PHP Version 5.4.37 Server API: CGI/FastCGI Memory_limit: 256MB output_buffering: no value
以下是我发送事件的示例代码:
<?PHP header("Content-Type: text/event-stream"); header("Cache-Control: no-cache"); header("Access-Control-Allow-Origin: *"); $lastEventId = floatval(isset($_SERVER["HTTP_LAST_EVENT_ID"]) ? $_SERVER["HTTP_LAST_EVENT_ID"] : 0); if ($lastEventId == 0) { $lastEventId = floatval(isset($_GET["lastEventId"]) ? $_GET["lastEventId"] : 0); } echo ":" . str_repeat(" ",2048) . "\n"; // 2 kB padding for IE echo "retry: 2000\n"; // event-stream $i = $lastEventId; while ($i <= 100) { if($i==100){ echo "data: stop\n"; ob_flush(); flush(); break; } else { echo "id: " . $i . "\n"; echo "data: " . $i . ";\n\n"; ob_flush(); flush(); sleep(1); } $i++; } ?>
<!DOCTYPE html> <html> <head> <Meta charset="utf-8" /> <title>EventSource example</title> <Meta http-equiv="X-UA-Compatible" content="IE=edge"> <script src="../jquery/eventsource.js"></script> <script> var es = new EventSource("events.PHP"); var listener = function(event) { console.log(event.data); var type = event.type; if (event.data == 'stop') { es.close(); } else { var div = document.createElement("div"); div.appendChild(document.createTextNode(type + ": " + (type === "message" ? event.data : es.url))); document.body.appendChild(div); } }; var errlistener = function(event) { es.close(); } es.addEventListener("open",listener); es.addEventListener("message",listener); es.addEventListener("error",errlistener); </script> </head> <body> </body> </html>
解决方法
一个很好的Web套接字教程
http://www.phpbuilder.com/articles/application-architecture/optimization/creating-real-time-applications-with-php-and-websockets.html
使用这种方法,你可以然后,如果你想要实现验证,所以服务器不只是发送块,它是由javascript请求发送块
所以你的客户可以说我需要块5,你的服务器实现类似的东西
$requestedChunk = 5; // this would be set by the javascript sending the request $chunkSize = 256; // this would be your chunk size; $readPossition = $requestedChunk * $chunkSize;
链接不再有效,所以这里是一个建立在Ratchet:https://blog.samuelattard.com/the-tutorial-for-php-websockets-that-i-wish-had-existed/