Фон :
Мне нужно создать простой сайт, который принимает входящий размещенный XML и отправляет XML на сервер через сокет-соединение, а затем отображает XML, отправленный обратно с сервера. Легкий горох.
Задача :
У меня не было проблем с использованием fsockopen () для подключения к серверу и отправки XML. Чтение XML с сервера было совершенно новой проблемой. Нормальный
while (!feof($fp)) {
echo fgets($fp);
}
не сработал, поскольку сервер возвращает одну строку XML и только одну строку XML (без информации о длине, eof, eol и т. Д.). Таким образом, он будет ждать, пока истечет время ожидания, отобразит полученный XML и ошибку времени ожидания. Моя проблема похожа на этого динозавра .
В двух словах я хочу прочитать XML на сокете и закрыть его, как только больше не будет отправлено данных (не ожидая тайм-аута). Установка таймаута на низкое значение также была недопустимой, поскольку ответ сервера может варьироваться от 2 до 30 секунд.
Решение :
После целого дня борьбы я решил поделиться следующим решением этой проблемы (критикуйте).
$fp = fsockopen("123.456.789.1", 80, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)";
} else {
$wait = true;
$out = '<samplexml><item>something</item></samplexml>';
// [1] disable blocking
stream_set_blocking($fp, 0);
fwrite($fp, $out);
while (!feof($fp)) {
$r = fgets($fp);
echo $r;
if (!strcmp($r, "")){
if (!$wait) {
// [2] has recieved data on this socket before
break;
}
} else {
$wait = false;
}
}
fclose($fp);
}
Оказывается, моей главной проблемой была блокировка . Итак, во-первых, [1] мне пришлось отключить stream_set_blocking, чтобы fgets () мог непрерывно проверять, стали ли доступны новые данные. Если не отключено, fgets () получит XML с сервера, а затем цикл будет зависать со второй попытки, поскольку он будет ждать, пока не станет доступно больше данных (чего никогда не будет).
Я знаю, что как только мы прочитаем некоторые данные, мы сможем немедленно закрыть соединение, если будут возвращены пустые fgets () (таким образом, мы все еще можем установить второй параметр fgets ( ) , если это необходимо).
После нескольких месяцев использования этого сайта я наконец-то получил возможность что-то опубликовать в stackoverflow.