Source d’événement -> Le serveur renvoie le stream d’événements en bloc plutôt que de retourner dans le bloc

J’ai un script php qui importe des données volumineuses à partir de fichiers CSV avec des validations.
Pour cela, je dois montrer les progrès à l’utilisateur. J’ai utilisé Event Streaming pour cela.
Quand je fais écho à quelque chose, je veux qu’il soit transféré au client un par un au lieu d’être envoyé en masse par le serveur.
J’avais déjà joué avec ob_start (), ob_implicit_flush () & ob_flush (), mais elles ne fonctionnaient pas.
Mon script fonctionne parfaitement sur un autre serveur. Les configurations de serveur ci-dessous sont données:

Configuration du serveur sur laquelle le code ne répond pas comme souhaité, par exemple

  OS: Linux
 PHP Version 5.4.36-0 + deb7u3
 API serveur: CGI / FastCGI 
 Memory_limit: 128M
 output_buffering: aucune valeur

Comme je l’ai dit, le code fonctionne correctement sur un autre serveur qui a la même configuration, c’est-à-dire

  OS: Linux
 PHP version 5.4.37
 API serveur: CGI / FastCGI 
 Memory_limit: 256 Mo
 output_buffering: aucune valeur

Voici mon exemple de code pour l’envoi de l’événement:

<?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  

Voici ma page client sur laquelle j’ai besoin de réponse:

     EventSource example    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);      

Votre meilleure méthode pour renvoyer des données cachées au navigateur consiste à utiliser Web Sockets pour que le client ouvre un socket sur votre lecteur de fichiers, puis vous pouvez découper les données au navigateur sans problème.

Une fois terminé, vous pouvez fermer le socket.

un bon tutoriel pour les sockets Web http://www.phpbuilder.com/articles/application-architecture/optimization/creating-real-time-applications-with-php-and-websockets.html

avec cette méthode, vous pouvez alors si vous voulez implémenter la vérification afin que le serveur ne se contente pas d’envoyer des morceaux, il envoie les morceaux sur demande par javascript

Donc, votre client pourrait dire que j’ai besoin d’un morceau 5 et que votre serveur implémente quelque chose comme

 $requestedChunk = 5; // this would be set by the javascript sending the request $chunkSize = 256; // this would be your chunk size; $readPossition = $requestedChunk * $chunkSize; 

J’avais un problème similaire. Les stream d’événements fonctionnaient comme prévu (en retournant des morceaux) sur un serveur utilisant le gestionnaire Apache 2.0 mais pas sur un serveur utilisant FastCGI (en le renvoyant en bloc). J’ai supposé que quelque chose dans FastCGI était le coupable et j’ai donc essayé de résoudre le problème en passant à CGI. Maintenant, le stream d’événements fonctionne comme prévu.

Que vous utilisiez CGI ou FastCGI, l’API du serveur se présente sous la forme de CGI / FastCGI. Je suppose donc que le serveur sur lequel il travaille est sous CGI et que le serveur sur lequel il ne fonctionne pas s’exécute sur FastCGI. Essayez de changer le serveur qui ne fonctionne pas en CGI.

Pour ce qui est de savoir pourquoi cela ne fonctionne pas dans FastCGI, je ne suis pas tout à fait sûr, mais à moins que cela ne soit nécessaire et que CGI ne soit pas possible, alors la solution ci-dessus devrait fonctionner.

Beaucoup de choses peuvent empêcher une réponse fragmentée telle que, mais sans s’y limiter:

  • Proxy ou tout autre mécanisme tampon sur le serveur Web
  • Lorsque “Tampon de sortie” est “activé” dans php.ini (vous devez explicitement le désactiver)
  • Lorsque gzip est activé sur le serveur Web

Vous devriez d’abord les vérifier.