|
|
|
| Есть скрипт каторый последовательно с помощью сокетов обращается к страницам и парсит их, приэтом на каждую обработку уходит 1-2 секунды, но для моей задачи необходимо одновременно обработать эти запросы. Слышал про неблокирующие сокеты, но чесно говоря не розобрался что это и с чем это едят. У меня пхп 5, скрпит работает как консольное приложение с локальной машины. ЕНе мог ыб кто нибудь мне подсказать возможно ли такое решение на пхп и если возможно как его реализовать. | |
|
|
|
|
|
|
|
для: KPETuH
(22.02.2007 в 10:58)
| | ап | |
|
|
|
|
|
|
|
для: KPETuH
(22.02.2007 в 13:04)
| | одновресменно ОБРАБАТЫВАТЬ полученные данные не выйдет - в PHP многопоточность не реализована... а обработка полученных данных - это все-таки код скрипта и тут уже неважно, сколько времени уходит на получение данных... а вообще - можно попробовать с помощью логики немного оптимизировать...
запрос - ожидание данных - получение данных 1 - запрос новых данных - обработка данных 1 - получение данных 2 - запрос новых данных - ...
т.е. пока идет ожидание данных по запросу обрабатывать полученные от прошлого апроса данные...
это как-то может ускорить работу скрипта, т.к. время ожидания максимально используется...
а можно попробовать еще сделать сразу несколько запросов, открывая несколько сокетов по разным дескрипторам.... и собственно читать их в разные фуферы... обрисую тока логику... т.к. функции не подскажу с ходу...
<?
$ok =array();
$hdr[1] = сокет+запрос (url1)
$hdr[2] = сокет+запрос (url2)
...
$hdr[N] = сокет+запрос (urlN)
while(count($ok) < count($hdr))
{
for ($i=0; $i<count($hdr); $i++)
{
if(isset($ok[$i])) // если данные по сокету уже обработаны - пропускаем его...
continue;
читаем из $hdr[i] в буфер $buff[$i];
если получены последние данные из $hdr[$i]
$ok[$i] = обработка $buff[$i]; // результат обработки помещаем в соответствующий элемент массива
};
};
закрываем сокеты $hrd[...]
?>
|
что-то типа такого... | |
|
|
|
|
|
|
|
для: ZuArt
(22.02.2007 в 13:48)
| | одновременно мне обрабатывать данные и не нада главна задержка идет как раз из-за того что чокеты открываются последовательно, спасибо попробую ваш вариант...
все же хотелось бы услышать немногои про неблокирующие сокеты что это такое и с чем его едяи и как особенности у них | |
|
|
|
|
|
|
|
для: KPETuH
(22.02.2007 в 14:07)
| | вот кажется функция fsockopen как раз открывает сокеты асинхронно, т.е. она не ожидает получения всех данных.. они просто наполняют буфер по мере поступления, а код скрипта выполняется дальше... а данные можно забрать из буфера в любое УДОБНОЕ время... даже кусками можно забирать... обработать - прочитать следующуу порцию... | |
|
|
|
|
|
|
|
для: ZuArt
(22.02.2007 в 14:16)
| | Победил проблему с помошью неблокирующих сокетов...Скорость отработки скрипта увеличилась с 2-3 минут до 10-20 секунд. :) Спасибо за помощь. | |
|
|
|
|
|
|
|
для: KPETuH
(27.02.2007 в 10:00)
| | =))) поздравляю ;) а заодно и код сюда попрошу ;) - мне лично не повредит его добавить в свою библиотеку ;) | |
|
|
|
|
|
|
|
для: ZuArt
(27.02.2007 в 10:21)
| | к сожалению код привести не могу так как там много конфиденциальной информации но за основу взят вот этот код
<?php
$sockets = array();
$done = false;
// будем работать, к примеру с набором
// ключевых слов
$keywords = fopen(”keywords.txt”, “r”);
// приступаем к многопоточной работе
while (!$done)
{
// если обнаружен файл,
// то прекращаем выполнение скрипта
if (file_exists(”stop-file”)) die;
// если число запущенных потоков меньше
// разрешенного максимума
// то запускаем потоки еще
if ($max_threads > count($sockets))
{
if (!feof($keywords))
{
$buffer = array();
// читаем ключевое слово
// в реальности в этот массив можно
// положить очень много всего
// а не только одно ключевое слово…
$buffer[] = trim(fgets($keywords));
// задаем данные для запуска сокета
// request.php - это тот файл,
// которые делает “дело”
$query_url = $path . “request.php”;
$url_info = parse_url($query_url);
$url_info[port] = ($url_info[port]) ? $url_info[port] : 80;
$url_info[path] = ($url_info[path]) ? $url_info[path] : “/”;
$url_info[query] = ($url_info[query]) ? “?” . $url_info[query] : “”;
// пакуем данные для передачи
// в генерирующий скрипт
// использование serialize очень удобно,
// так как позволяет
// залить в request.php мегабайты данных
$request = serialize($buffer);
// формируем запрос для передачи по сокету
$query = “POST ” . $url_info[path] . ” HTTP/1.1\r\n”;
$query = $query . “Content-Type: text/xml\r\n”;
$query = $query . “Host: ” . $url_info[host] . “\r\n”;
$query = $query . “Content-length: ” . (strlen($request)) . “\r\n\r\n”;
$query = $query . $request;
// создаем сокет, переводим его
// в неблокирующий режим и запускаем
// обработчик запросов
$errno = 0;
$error = “”;
$socket = fsockopen($url_info[host], $url_info[port], $errno, $error, 30);
stream_set_blocking($socket, 0);
stream_set_timeout($socket, 3600);
fputs($socket, $query);
// запоминаем запущенный сокет
$sockets[md5(time())] = $socket;
}
}
// читаем данные из сокета. формально они нам
// не нужны, но это позволяет
// отработать обработчкику запросов
reset($sockets);
while ($socket = current($sockets))
{
if (feof($socket))
{
// убиваем сокет, который отработал
unset($sockets[key($sockets)]);
}
else
{
// читаем данные из сокета
$temp = fgets($socket, 1000);
}
// обрабатываем следующий сокет
next($sockets);
}
// делаем небольщую задержку,
// иначе загруженность сервера
// приближается к 100 процентам
//не знаю как загрузка процессора но без паузы в несколько микросекунд работать отказывается
sleep(1);
// если нет активных сокетов, то можно выходить
if (count($sockets) == 0)
$done = true;
}
fclose($keywords);
?>
|
| |
|
|
|