Сокеты и timeout

alpes

Весь мир на ладони
Сокеты и timeout

Как правильно ограничиться от подвисания приложения, если удаленный сервер упадет или станет не доступным?
PHP:
# Например такой пример с не существующим хостом:
  $cfgServer = "website.kiev.ua";
  $cfgPort = 80;
  $cfgTimeOut = 2; // столько секунд должно пробовать соединиться
  $get="GET / HTTP/1.0\r\nHost: ".$cfgServer."\r\n\r\n";
  $t=time();
  $sd=fsockopen($cfgServer, $cfgPort, &$errno, &$errstr, $cfgTimeOut);
  if($sd) {echo "Ok!"; fclose($sd);}
  else echo "Fsockopen failed.<br>\nTimeopen: ".(time()-$t)."<br>\n(".$errno.") ".$errstr."<br>\n";
У меня этот пример в среднем дуплит 40 секунд на fsockopen...

Может это из-за сейфмоды?
И если да то как это обойти при данном режиме?
 

alpes

Весь мир на ладони
Necromant: # Например такой пример с не существующим хостом
Задача в том чтобы отвалиться по таймауту и не ждать все 40 секунд.
 

Tor

Новичок
Например такой пример с не существующим хостом
тебе уже сказали, что не сам fsockopen ждет 40 секунд, а резолв адреса
тренируйся на существующих адресах
если не знаешь, существует ли хост, делай отдельно nslookup (кстати, правильнее dig) и отдельно fsockopen
 

alpes

Весь мир на ладони
парни, к чему все это, вы что вопросы не читаете?!

:
Как правильно ограничиться от подвисания приложения, если удаленный сервер упадет или станет не доступным?

а это пример для отладки работы. специально взят не существующий, о чем и сказано.
ф-ия выполнения fsockopen должна бы оборваться по таймауту (2 секунды), но работает, вроде все время что в max_execution_time,
и после только продолжается выполнение приложения.
Проблему вижу в сейфмоде, но интересует как можно выполнить обрыв и продолжение работы приложения при данном режиме.
 

alpes

Весь мир на ладони
мда, кто еще уперся...

All, не уж то никто не сталкивался с проблемой таймаутов? Приложение должно отработать без подвисаний.
 

kruglov

Новичок
Есть еще проблема, что мы сконнектились с серваком через fsockopen, все зашибись, отправили ему запрос, начинаем читать ответ и ... продолжаем его читать полчаса, потому как удаленный сервер не торопится с ответом.

Как в этом случае отвалиться по таймауту?
 

alpes

Весь мир на ладони
с этой проблемой можно разобраться просто:
PHP:
stream_set_timeout($sd, $cfgTimeOut);
$str=fgets($sd,512);
$info=stream_get_meta_data($sd);
if($info['timed_out']) die("timed_out..");
//...
не могу разобраться с fsockopen :(

-~{}~ 08.06.05 18:17:

Собственно придумал решить проблему путем вызова параллельного обработчика который уже и будет коннектится к удаленному серверу и если все Ок, то писать что нить в БД/ файл для вызвавшего приложения. Ну а вызвавшее приложение после усыпания должно посмотреть ответ (если он уже будет к этому времени) и принять уже соответствующее решение.
PHP:
# MAIN-script
  $cfgTimeOut=4;
  $sd=fsockopen($_SERVER["SERVER_NAME"], 80); 
  if(!$sd) fputs($sd, "GET /socer.php?a=[.здесь нужные гет параметры.] HTTP/1.0\r\nHost: ".$_SERVER["SERVER_NAME"]."\r\n\r\n");
  fclose($sd);
  sleep($cfgTimeOut);
  ... // читаем: появились ли данные? (если socer.php успешно выполнил fsockopen и принял ответ)


# файл socer.php
  $cfgServer = "website.kiev.ua";
  $cfgPort = 80;
  $cfgTimeOut = 2;
  $start=time();
  $sd=fsockopen($cfgServer, $cfgPort, &$errno, &$errstr, $cfgTimeOut);
  if(!$sd) exit;
  fputs($sd, "GET /a.php?a=t HTTP/1.0\r\nHost: ".$cfgServer."\r\n\r\n");
  ... // читаем данные от удаленного сервера
  ... // пишем данные в данно обменник для вызывающего приложения (по GET параметрам)
ps. при выключенной сейфмоде этим можно было бы не перениматься. Правда на практике при этом выполнение fsockopen и занимало время выполнения от $cfgTimeOut до $cfgTimeOut + ~5 секунд (непонятно откуда они брались!), но все же это в пределах нормы чтобы юзер не начал нервничать из-за подвисшего открытия страницы.
 
Сверху