Получение данных из файла ассинхронным запросом, при его наполнении циклом

sanu0074

Новичок
Здравствуйте. Есть цикл, который делает операции и ложит текст в файл таким методом:
PHP:
    public function addToConsole($str,$class="n"){
        $currentText = file_get_contents($this->console);
        $console = fopen($this->console, "w");
        fwrite($console, $currentText."<p>".date("Y/m/d G:i:s")." <span class='".$class."'>".$str."</span></p>");
        fclose($console);
    }
Цикл этот может длиться около 20 секунд.

Во время выполнения этого цикла, посылаются запросы с интервалом в 2 сек. к методу который возвращает содержимое этого файла:
PHP:
    public function getConsole(){
        exit(file_get_contents($this->user->console));
    }
Проблема в том, что содержимое файла, возвращается только через 20 сек (время которое выполняется скрипт с циклом), а не по мере его наполнения каждые 2 сек. Т.е. файл должен постепенно расти, и его куски должны возвращаться методом getConsole() по мере наполнения, так мы получаем лог действий, пока юзер ждет до конца выполнения скрипта - он видит что делается в этот момент.
Даже на сервере (win7, php 5.5), проверяю содержимое файла, он пуст при старте скрипта = 0 кб, и все 20сек выполнения он тоже пуст (нет содержимого) и вес = 0кб, но через 20сек, по окончанию работы скрипта он сразу моментально весит 19кб и в нем есть текст.

Как победить эту задачу?
 

keltanas

marty cats
Можно еще проще:
PHP:
file_put_contents(
    $this->console,
    "<p>".date("Y/m/d G:i:s")." <span class='".$class."'>".$str."</span></p>",
    FILE_APPEND | LOCK_EX
);
 

sanu0074

Новичок
Так не работает:
PHP:
    public function addToConsole($str,$class="n"){
        $currentText = file_get_contents($this->console);
        file_put_contents(
            $this->console,
            "<p>".date("Y/m/d G:i:s")." <span class='".$class."'>".$str."</span></p>",
            FILE_APPEND | LOCK_EX
        );
    }
и так не работает:
PHP:
    public function addToConsole($str,$class="n"){
        $currentText = file_get_contents($this->console);
        $console = fopen($this->console, "w");
        flock($console, LOCK_EX);
        fwrite($console, $currentText."<p>".date("Y/m/d G:i:s")." <span class='".$class."'>".$str."</span></p>");
        flock($console, LOCK_UN);
        fflush($console);
        fclose($console);
    }
результат, тот же(
 

keltanas

marty cats
А строчка `$currentText = file_get_contents($this->console);` в первом варианте зачем?
Что именно не работает? Как проверяешь?
 

sanu0074

Новичок
А строчка `$currentText = file_get_contents($this->console);` в первом варианте зачем?
да, это лишняя, я первый раз делал без append
Что именно не работает? Как проверяешь?
В файле информация появляется только после окончания работы скрипта, как в исходном варианте:
PHP:
public function addToConsole($str,$class="n"){
        $currentText = file_get_contents($this->console);
        $console = fopen($this->console, "w");
        fwrite($console, $currentText."<p>".date("Y/m/d G:i:s")." <span class='".$class."'>".$str."</span></p>");
        fclose($console);
    }
нужно чтоб на каждой итерации цикла в нем появлялись данные. Проверяю таймером с ajax запросами и смотря файл на сервере (20 сек на это хватает)
 

keltanas

marty cats
попробуй проверять через tail -f
проверь, как вызывается метод addToConsole()?
напиши тестовый скрипт, который будет в цикле через sleep(1) толкать данные в метод.
подозреваю, что не работает где-то в другом месте...
 

accido

Новичок
Так не работает:
PHP:
    public function addToConsole($str,$class="n"){
        $currentText = file_get_contents($this->console);
        file_put_contents(
            $this->console,
            "<p>".date("Y/m/d G:i:s")." <span class='".$class."'>".$str."</span></p>",
            FILE_APPEND | LOCK_EX
        );
    }
и так не работает:
PHP:
    public function addToConsole($str,$class="n"){
        $currentText = file_get_contents($this->console);
        $console = fopen($this->console, "w");
        flock($console, LOCK_EX);
        fwrite($console, $currentText."<p>".date("Y/m/d G:i:s")." <span class='".$class."'>".$str."</span></p>");
        flock($console, LOCK_UN);
        fflush($console);
        fclose($console);
    }
результат, тот же(
nado tak
fflush($console);flock($console, LOCK_UN);
 

sanu0074

Новичок
Сделал так, работает теперь:
PHP:
    public function addToConsole($str,$class="n"){
        sleep(1);
        $currentText = file_get_contents($this->console);
        $console = fopen($this->console, "w");
        fwrite($console, $currentText."<p>".date("Y/m/d G:i:s")." <span class='".$class."'>".$str."</span></p>");
        fflush($console);
        flock($console, LOCK_UN);
        fclose($console);
    }
на сервере в папке в фал постепенно добавляется текст, но ajaxo'm получается получить содержимое файла только после полного выполнения скрипта, наверно сессия блочится и брауузер не может послать тут же еще один запрос.
Как выйти из этой ситуации?
 

keltanas

marty cats
Мне кажется, стоит написать отдельный скрипт, который будет транслировать дельту лога для ajax-запросов.
 
  • Like
Реакции: WMix

keltanas

marty cats
Про какую сессию идет речь?
За 2 дня уже можно было бы 10 таких скриптов написать и выяснить самому ;)
 

sanu0074

Новичок
При использовании сессий, ее данные хранятся в одном файле, который оказывается заблокированным с момента вызова session_start и до окончания работы скрипта.
десяток асинхронных запросов к PHP-скрипту выстраивается в очередь вместо того, чтобы отрабатывать параллельно....
Я не знаю как правильно и безопасно обойти эту проблему, т.е. не ждать пока выполниться основной скрипт, а во время выполнения дать возможность выполняться другим (в данном случае, который достает инфу из файла console.txt)
 
Сверху