Чтение результатов массива PHP в режиме реального времени с помощью Javascript

Я, конечно, не могу решить эту проблему самостоятельно после нескольких многодневных попыток. Это проблема:

Нам нужно отобразить на экране информацию (HTML), которая генерируется в реальном времени внутри файла PHP.

PHP выполняет очень активное сканирование, возвращая огромные массивы URL-адресов, каждый URL-адрес должен отображаться в режиме реального времени в HTML, как только PHP его захватывает, поэтому мы используем Ob_flush() и методы очистки, чтобы отображать и печатать массивы, как только мы их получили.

Между тем нам нужно как-то отображать эту информацию, чтобы пользователи могли видеть ее, пока она работает (поскольку это может занять более одного часа, пока она не закончится).

Насколько я понимаю, это невозможно сделать с помощью AJAX, так как нам нужно сделать только 1 запрос и прочитать информацию внутри массива. Я также не совсем уверен, что комет может это сделать что-то вроде этого, так как он прервет соединение, как только получит новую информацию, а размер массива действительно быстро увеличивается.

Кроме того, просто чтобы усложнить ситуацию, нет реальной необходимости печатать или отображать информацию (URL) внутри массива, поскольку файл HTML включается в качестве пользовательского интерфейса того же файла, который обрабатывает и генерирует массив, который нам нужно отобразить.

Короче говоря; нам нужно разместить здесь:

<ul>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    ...
</ul>

Непрерывный и обновляемый в режиме реального времени список URL-адресов, которые создаются и помещаются в массив, 1000 строк ниже, в цикле PHP.

Любая помощь будет действительно более чем оценена. Заранее спасибо!


person Chris Russo    schedule 14.09.2012    source источник
comment
Будет ли работать запись массива PHP в файл и его анализ с помощью Javascript? Вы можете ajax файл в любое время, и он будет иметь все результаты, в то время как PHP постоянно добавляет к нему.   -  person Jon Egeland    schedule 15.09.2012
comment
Привет, Джон! Большое спасибо за быстрый ответ. Это хороший подход, и мы уже думали об этом, однако это невозможно, так как нагрузка уже очень велика.   -  person Chris Russo    schedule 15.09.2012
comment
было любопытно, сработали ли сокеты для вас....   -  person Stephen    schedule 18.09.2012


Ответы (5)


Попробуйте веб-сокеты.

Они обеспечивают связь между клиентом и сервером в режиме реального времени, а использование socket.io обеспечивает кросс-браузерную совместимость. В основном это дает вам те же результаты, что и длинный опрос / комета, но между запросами меньше накладных расходов, поэтому он быстрее.

В этом случае вы должны использовать веб-сокеты для отправки клиенту обновлений о текущем состоянии обработки (или о том, что он делал).

См. это Использование PHP с Socket.io

person Jamund Ferguson    schedule 14.09.2012
comment
Меня здесь многое заставило, а не просто опубликовать ссылку в качестве ответа, я предлагаю вам сделать то же самое, объяснив, почему WebSockets были бы более идеальными, чем уже опубликованные ответы, и вы правы, это лучшее решение из всех.. ;) - person dbf; 15.09.2012
comment
Я знаком с ними, и звучит как хорошая возможность, я посмотрю на это, есть ли какое-либо решение, которое вы могли бы предложить для реализации этой реализации? Большое спасибо! - person Chris Russo; 15.09.2012
comment
Спасибо, мы продолжаем этот подход!! - person Chris Russo; 15.09.2012

Предположим, вы использовали схему, в которой PHP писал на сервер Memcached.

каждый ключ вы пишете как rec1, rec2, rec3

Вы также сохраняете current_min и current_max

У вас есть пользователь, постоянно опрашивающий с помощью ajax. Для каждого запроса они включают последний ключ, который они видели, назовите это k. Затем сервер возвращает все записи от k до max.

Если сразу нет доступных записей, сервер переходит в цикл ожидания максимум, скажем, на 3 секунды, проверяя наличие новых записей каждые 100 мс.

Если записи становятся доступными, они немедленно отправляются.

Всякий раз, когда клиент получает обновления или соединение разрывается, он немедленно запускает новый запрос...

Запись новой записи — это просто вопрос вставки max+1 и увеличения min и max, где max-min — это количество записей, которые вы хотите оставить доступными...

person Stephen    schedule 14.09.2012
comment
Спасибо Стивен, это интересный подход. Как вы думаете, это должно работать быстрее, чем база данных или параметры сокета? - person Chris Russo; 15.09.2012
comment
Конечно, быстрее, чем опция db, так как вставка/удаление memcached будет O (1) и полностью сохранена в памяти. Вероятно, веб-сокеты оптимальны для отправки данных, но в настоящее время они несколько непоследовательно поддерживаются браузерами. FF ненадолго удалил их из FF4 и вернул в FF5, потому что они обнаружили проблему безопасности, которая присутствовала на уровне стандартов. - person Stephen; 15.09.2012
comment
Большое спасибо, Стивен, отличное решение. - person Chris Russo; 15.09.2012

Альтернативой веб-сокетам является COMET.

Я написал статью об этом вместе с < href="http://treehousetim.com/2012/05/04/comet-update-workaround-blocked-connections/" rel="nofollow">продолжение с описанием моего опыта.

По моему опыту, COMET работает быстро. За веб-сокетами определенно будущее, но если вы находитесь в ситуации, когда вам просто нужно это сделать, вы можете настроить и запустить COMET менее чем за час.

Определенно здесь нужна какая-то структура разделяемой памяти - возможно, временная таблица в памяти в вашей базе данных или Memcached, как уже предложил Стивен.

person Tim G    schedule 14.09.2012

Я думаю, что лучшим способом сделать это было бы, чтобы первый PHP-скрипт сохранял каждую запись в базу данных (возможно, MySQL или SQLite), а затем имел второй PHP-скрипт, который считывает из базы данных и выводит самые новые записи. Затем используйте AJAX, чтобы время от времени вызывать этот скрипт и добавлять записи, которые он отправляет, в вашу таблицу. Вам нужно будет найти способ запуска первого скрипта.

javascript должен записать идентификатор последнего URL-адреса, который у него уже есть, и отправить его в запросе AJAX, тогда PHP может выбрать все строки с идентификаторами больше этого.

Если количество URL-адресов настолько велико, что вы не можете хранить такую ​​большую базу данных на своем сервере (можно спросить, как браузер справится с такой большой таблицей!), то вы всегда можете иметь PHP-скрипт, который выводит самые последние записи, а также удаляет их из базы данных.

Редактировать: при выполнении большого количества вставок MySQL есть несколько вещей, которые вы можете сделать, чтобы ускорить его. Здесь есть отличный ответ с их подробным описанием. Короче говоря, используйте MyISAM и введите как можно больше строк в одном запросе (имейте буферный массив в PHP, в который вы добавляете URL-адреса, и когда он заполнен, вставьте весь буфер в один запрос).

person gandaliter    schedule 14.09.2012
comment
Привет Гандалитер, большое спасибо за ваш комментарий! это самая быстрая реализация, которую мы сделали в системе, мы уже пробовали этот подход, но он все еще сильно влияет на производительность, так как это огромное количество запросов на вставку. Кроме того, это также подразумевает создание второго файла только для чтения информации, которая обрабатывается в том же источнике. Что-нибудь еще приходит вам на ум? - person Chris Russo; 15.09.2012

If I were you , I try to solve this with two way .
First of all I encode the output part array  with json and with the setTimeout function with javascript I'll decode it and append with <ul id="appendHere"></ul> so 

когда список обновляется, он автоматически обновляется. Как cronjob с js.

Второй способ, если вы говорите, что я не мог получить вывод во время обработки, поэтому использование вставки данных в mysql бессмысленно, я думаю, используйте MongoDb или т. Д. Для увеличения скорости. Кстати, вы достигнете того, что вам нужно, с помощью своего ключа и никогда не дублируете вставленное значение.

person Emre Karataşoğlu    schedule 14.09.2012