Я пытаюсь реализовать индикатор выполнения для импорта записей в базу данных.
Импорт запускается с использованием $ .post (…) jQuery, отправляемого в скрипт php на сервере.
Я попробовал несколько подходов:
PHP для импорта это что-то вроде:
foreach($importProduct as $ip){
$_SESSION['importedProducts'] += 1;
// ... do the import-stuff
}
А затем получить прогресс импорта с помощью EventSource
var jsonStream = new EventSource('eventSource.php');
if(typeof(EventSource) === "undefined"){
alert('browser doesn\'t support EventSource');
}else{
console.log('fetching stream');
jsonStream.onmessage = function (e) {
console.log('stream: ' + e.data);
$('#eventReturn').html(e.data);
//var message = JSON.parse(e.data);
// handle message
};
}
и в PHP-скрипте
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
while(1){
echo 'data: {"imported":"'.$_SESSION['importedProducts'].'","total":"'.$_SESSION['totalProductsToImport'].'"}';
echo "\n\n";
ob_flush();
flush();
sleep(1);
}
Что, очевидно, не работает, так как СЕССИЯ не обновляется между вызовами.
Запись прогресса в файл и последующее его считывание каждую секунду кажется излишней нагрузкой …
Еще одна вещь, которую я попробовал, — это использование js-функции, которая вызывает себя каждую секунду и пытается получить прогресс из того же скрипта — но она зависает, пока не завершится импорт-скрипт
function uploadProgress(){
// Fetch the latest data
$.get('progress.php', function(data){
console.log(data);
});
setTimeout(uploadProgress, 5000);
}
Есть идеи?
Примечания: я запускаю сеанс при любом вызове (session_start). Я знаю, что «while (1)» создает бесконечный цикл … 🙂
Я нашел решение.
Хитрость заключалась в том, чтобы открыть и закрыть сеанс между вызовами.
Итак, в import-скрипте:
foreach($importProduct as $ip){
session_start();
$_SESSION['importedProducts'] += 1;
session_write_close();
// ... do the import-stuff
}
и в прогресс-скрипте:
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
while(1){
session_start();
echo 'data: {"imported":"'.$_SESSION['importedProducts'].'","total":"'.$_SESSION['totalProductsToImport'].'"}';
echo "\n\n";
ob_flush();
flush();
session_write_close();
sleep(1);
}
Теперь сессия постоянно обновляется, и я могу использовать EventSource-подход
Других решений пока нет …