За последние 24 часа нас посетили 54658 программистов и 1719 роботов. Сейчас ищут 2119 программистов ...

Тайм аут функции

Тема в разделе "PHP для новичков", создана пользователем 715kg, 18 фев 2014.

  1. 715kg

    715kg Активный пользователь

    С нами с:
    2 мар 2013
    Сообщения:
    147
    Симпатии:
    0
    Здравствуйте, такой вопрос, можно ли сделать тайм аут функции. Допустим вызываю функцию так.


    Код (Text):
    1. $serv=info($r['top']);
    Если допустим функция не отдала ответ за 3 секунды, то вступало бы в силу код

    Код (Text):
    1. $serv=0;
    Можно ли такое сделать?
     
  2. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    А что внутри?
     
  3. 715kg

    715kg Активный пользователь

    С нами с:
    2 мар 2013
    Сообщения:
    147
    Симпатии:
    0
    А внутри функция сбора информации.

    Код (Text):
    1. <?php
    2.  
    3.  
    4.   if(!function_exists('getmicrotime')) {
    5.     function getmicrotime() {
    6.         list($usec, $sec) = explode(" ", microtime());
    7.         return ((float)$usec + (float)$sec);
    8.     }
    9. }
    10.   function cutchar(&$string)
    11.   {
    12.    $char = substr($string, 0, 1);
    13.     $string = substr($string, 1);
    14.     return $char;
    15.   }
    16.   function cutbyte(&$string)
    17.   {
    18.     $byte = ord(substr($string, 0, 1));
    19.     $string = substr($string, 1);
    20.     return $byte;
    21.   }
    22.   function cutstring(&$string)
    23.   {
    24.     $str = substr($string, 0, StrPos($string, chr(0)));
    25.     $string = substr($string, StrPos($string, chr(0))+1);
    26.     return $str;
    27.   }
    28.   function cutshort(&$string)
    29.   {
    30.     $short = substr($string, 0, 2);
    31.     list(,$short) = @unpack("S", $short);
    32.     $string = substr($string, 2);
    33.     return $short;
    34.   }
    35.   function cutlong(&$string)
    36.   {
    37.     $long = substr($string, 0, 4);
    38.     list(,$long) = @unpack("l", $long);
    39.     $string = substr($string, 4);
    40.     return $long;
    41.   }
    42.   function pastelong($long)
    43.   {
    44.     return pack("l", $long);
    45.   }
    46.   function cutfloat(&$string)
    47.   {
    48.     $float = substr($string, 0, 4);
    49.     list(,$float) = @unpack("f", $float);
    50.     $string = substr($string, 4);
    51.     return $float;
    52.   }
    53.  
    54.   function request($request,$server)
    55.   {
    56.     list($ip,$port) = explode(":", $server);
    57.     $request = "\xFF\xFF\xFF\xFF".$request."\x00";
    58.     $fp = @fsockopen('udp://'.$ip, $port);
    59.     if (!$fp) return false;
    60.     @fwrite($fp, $request);
    61.     socket_set_timeout($fp, 1);
    62.     $string=fread($fp, 10240);
    63.     @fclose($fp);
    64.     return $string;
    65.   }
    66.  
    67.   function A2A_PING($ip, $port) {
    68.     $st = request("\x69",$ip,$port);
    69.     if (!$st) return false;
    70.     $st = substr($st, 4);
    71.     if (substr($st, 0, 1) != "\x6A") return false; else return true;
    72.   }
    73.  
    74.  
    75.  
    76.  
    77.  
    78.  function serverInfo($server) {
    79. $timeStart = getmicrotime();
    80.  $st = request("\x54Source Engine Query", $server);
    81.     if (!$st) return false;
    82.     $st = substr($st, 4);
    83.     $result['ping'] = (int)((getmicrotime() - $timeStart)*10000);
    84.    
    85.     if (substr($st, 0, 1) == "\x49") {
    86.  
    87.  
    88.  $result['status'] = "on";
    89.       $result['version_if'] = cutbyte($st); // Byte: Network version
    90.       $result['version_if2'] = cutbyte($st); // Byte: Network version
    91.       $result['name'] = cutstring($st); // String: The server's name, eg: "Recoil NZ CS Server #1"
    92.       $result['map'] = cutstring($st); // String: The current map being played, eg: "de_dust"
    93.       $result['game'] = cutstring($st); // String: The name of the folder containing the game files, eg: "cstrike"
    94.       $result['gamename'] = cutstring($st); // String: A friendly string name for the game type, eg: "Counter Strike: Source"
    95.       $result['id'] = cutshort($st); // Short: Steam Application ID
    96.       $result['players'] = cutbyte($st); // Byte: The number of players currently on the server
    97.       $result['max_players'] = cutbyte($st); // Byte: Maximum allowed players for the server
    98.       $result['bots'] = cutbyte($st); // Byte: Number of bot players currently on the server
    99.       $result['dedicated'] = cutchar($st); // Char: 'l' for listen, 'd' for dedicated, 'p' for SourceTV
    100.       $result['os'] = cutchar($st); // Char: Host operating system. 'l' for Linux, 'w' for Windows
    101.       $result['password'] = cutbyte($st); // Byte: If set to 0x01, a password is required to join this server
    102.       $result['vac'] = cutbyte($st); // Byte: if set to 0x01, this server is VAC secured
    103.       $result['gameversion'] = cutstring($st); // String: The version of the game, eg: "1.0.0.14"
    104.      
    105. if($result['version_if'] == 73 && $result['version_if2'] == '48'){
    106. $result['version'] = '47';
    107. }else{
    108. $result['version'] = '73';
    109. }
    110.  
    111.  
    112.     } elseif (substr($st, 0, 1) == "\x6D") {
    113.       $result['status'] = "on";
    114.       $result['type'] = cutchar($st); // Char: 'm' (0x6D) - For GoldSrc
    115.       $result['ip'] = cutstring($st); // String: Game Server IP address and port
    116.       $result['name'] = cutstring($st); // String: The server's name, eg: "Recoil NZ CS Server #1"
    117.       $result['map'] = cutstring($st); // String: The current map being played, eg: "de_dust"
    118.       $result['game'] = cutstring($st); // String: The name of the folder containing the game files, eg: "cstrike"
    119.       $result['gamename'] = cutstring($st); // String: A friendly string name for the game type, eg: "Counter  Strike: Source"
    120.       $result['players'] = cutbyte($st); // Byte: The number of players currently on the server
    121.       $result['max_players'] = cutbyte($st); // Byte: Maximum allowed players for the server
    122.       $result['version'] = cutbyte($st); // Byte: Network version
    123.       $result['dedicated'] = cutchar($st); // Char: 'l' for listen, 'd' for dedicated, 'p' for SourceTV
    124.       $result['os'] = cutchar($st); // Char: Host operating system. 'l' for Linux, 'w' for Windows
    125.       $result['password'] = cutbyte($st); // Byte: If set to 0x01, a password is required to join this server
    126.       $result['ismod'] = cutbyte($st); // Byte: If set to 0x01, this byte is followed by ModInfo
    127.       $result['vac'] = cutbyte($st); // Byte: if set to 0x01, this server is VAC secured
    128.       $result['bots'] = cutbyte($st); // Byte: Number of bot players currently on the server
    129.       if ($result['ismod'] == 1) {
    130.        $result['status'] = "on";
    131.        $result['urlinfo'] = cutstring($st); // String: URL containing information about this mod
    132.         $result['urldl'] = cutstring($st); // String: URL to download this mod
    133.         $result['nul'] = cutbyte($st); // Byte: 0x00
    134.         $result['modversion'] = cutlong($st); // Long: Version of the installed mod
    135.         $result['modsize'] = cutlong($st); // Long: The download size of this mod
    136.         $result['svonly'] = cutbyte($st); // Byte: If 1 this is a server side only mod
    137.         $result['cidll'] = cutbyte($st); // Byte: If 1 this mod has a custom client dll
    138.       }
    139.     } else return false;
    140.     return $result;
    141.   }
    142.  
    143.  
    144.    
    145.    
    146.   function A2S_SERVERQUERY_GETCHALLENGE($server) {
    147.     $st = request("\x57",$ip,$port);
    148.     if (!$st) return false;
    149.     $st = substr($st, 4);
    150.     if (substr($st, 0, 1) != "\x41") return false; else return cutlong(substr($st, 1));
    151.   }
    152.   function A2S_RULES($server, $challenge) {
    153.     $st = request("\x56".pastelong($challenge),$ip,$port);
    154.     if (!$st) return false;
    155.     $st=substr($st, 4);
    156.     if (substr($st, 0, 1) == "\x41") {
    157.       $challenge = cutlong(substr($st, 1));
    158.       $st = request("\x56".pastelong($challenge),$ip,$port);
    159.       if (!$st) return false;
    160.       $st = substr($st, 4);
    161.     }
    162.     if (substr($st, 0, 1) != "\x45") return false;
    163.     $result['Type'] = cutchar($st); // Char: Should be equal to 'E'
    164.     $result['Num Rules'] = cutshort($st); // Short: The number of rules reported in response
    165.     for ($i = 1; $i <= $result['Num Rules']; $i++) {
    166.       $result['Rule Name'][$i] = cutstring($st); // String: The name of the rule
    167.       $result['Rule Value'][$i] = cutstring($st); // String: The rule's value
    168.     }
    169.     return $result;
    170.   }
    171.  
    172.   function A2S_PLAYER($host) {
    173.     $st = request("\x55".pastelong($challenge),$host,$port);
    174.     if (!$st) return false;
    175.     $st = substr($st, 4);
    176.     if (substr($st, 0, 1) == "\x41") {
    177.       $challenge = cutlong(substr($st, 1));
    178.       $st = request("\x55".pastelong($challenge),$host,$port);
    179.       if (!$st) return false;
    180.       $st = substr($st, 4);
    181.     }
    182.     if (substr($st, 0, 1) != "\x44") return false;
    183.     $result['Type'] = cutchar($st); // Char: Should be equal to 'D'
    184.     $result['Num Players'] = cutbyte($st); // Byte: The number of players reported in response
    185.     for ($i = 1; $i <= $result['Num Players']; $i++) {
    186.       $result['Index'][$i] = cutbyte($st); // Byte: The index into [0.. Num Players] for this entry
    187.       $result['Player Name'][$i] = cutstring($st); // String: Player's name
    188.       $result['Kills'][$i] = cutlong($st); // Long: Number of kills this player has
    189.       $result['Time connected'][$i] = cutfloat($st); // Float: The time in seconds this player has been connected
    190.     }
    191.     return $result;
    192.   }
    193.  
    194.  
    195.  /*
    196. function getlistservers(){
    197. //$sql = "SELECT adress
    198.         FROM   amx_servers";
    199. $result = mysql_query($sql);
    200. dbquery("SELECT adress FROM amx_servers");
    201.     if (mysql_num_rows($result) == 0) {
    202.         echo "No Servers";
    203.         exit;
    204.     }
    205.  
    206. if (mysql_error()!=='') return mysql_error
    207. $result=array();
    208. while ($row=dbarray(adress)) $result[]=$row;
    209. // или $result[$row['adress']]=$row так красивее
    210.  
    211. return $result
    212. }
    213. */
    214.  
    215.  //print_r(serverInfo("95.188.107.104:27037"));
    216. //print_r(A2S_RULES("95.31.133.189:27666",A2S_SERVERQUERY_GETCHALLENGE("95.31.133.189:27666")));
    217. //print_r(A2S_PLAYER("91.211.117.26:27017"));
    218.  
    219. ?>
     
  4. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    Есть два варианта, первый - считать это время в функции. Второй - использовать ALRM сигнал http://php.ru/manual/function.pcntl-alarm.html, но нужно разобраться, как работают сигналы в php вообще. Ну и это не спасет, если какой-то сокет задумался.
     
  5. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    логично предположить, что он просто хочет что-то откуда-то получить по урлу или типа того
    так что логично установить время обрыва по таймауту при подключении.

    я не знаю как, но это естественная настройка, наверняка она где-то недалеко.
     
  6. 715kg

    715kg Активный пользователь

    С нами с:
    2 мар 2013
    Сообщения:
    147
    Симпатии:
    0
    Вроде есть

    Код (Text):
    1. socket_set_timeout($fp, 1);
    В коде. Выставлена 1 секунда. Но по каким то причинам если сервер недоступен, он все равно ожидает около 10 секунд, после выбивает что сервер отключен.

    Добавлено спустя 4 минуты 4 секунды:
    А не эта ли удача???

    Код (Text):
    1. <?php
    2. $fp = fsockopen ( "udp://127.0.0.1" , 13 , $errno , $errstr );
    3. if (! $fp ) {
    4. echo "ERROR: $errno - $errstr<br />\n" ;
    5. } else {
    6. fwrite ( $fp , "\n" );
    7. echo fread ( $fp , 26 );
    8. fclose ( $fp );
    9. }
    10. ?>
    Но что то разобраться не могу(
     
  7. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    возможно ТОТ сервер отвечает тебе с задежкой. т.е. этот таймаут отвечает за облом неудачной попытки соединения. А у тебя возможно она удачная, я тот сервак держит паузу специально.
     
  8. 715kg

    715kg Активный пользователь

    С нами с:
    2 мар 2013
    Сообщения:
    147
    Симпатии:
    0
    Хмм, так вот как то нужно поставить таймаут на ответ, даже если он удачный. Нужно обрывать за 1 сек. Не успел сервер за 1 сек ответить, его проблема.
     
  9. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    это надо сначала выяснить, где грабли. Ты посмотри детально, на открытие сколько уходит, на каждое чтение сколько. Тогда и ясно будет.
     
  10. 715kg

    715kg Активный пользователь

    С нами с:
    2 мар 2013
    Сообщения:
    147
    Симпатии:
    0
    Чтение быстрое. Остановка идет как раз на получение данных. Видимо вы были правы сказав что сервер держит запрос. Коннект есть, а вот данные поступают только через определенное время.
     
  11. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    С точностью наоборот. stream_set_timeout отвечает за таймаут чтения/записи. За таймаут подключения отвечает соответствующий аргумент fsockopen.

    Добавлено спустя 10 минут 21 секунду:
    Вам нужно делать как-то так
    Код (Text):
    1.  
    2.     stream_set_blocking($fp, FALSE );
    3.     stream_set_timeout($sock, $timeout);
    4.     $info = stream_get_meta_data($sock);
    5.  
    6.     while (!feof($sock) && !$info['timed_out']) {
    7.         $file .= fgets($sock, 4096);
    8.         $info = stream_get_meta_data($sock);
    9.     }
    10.  
    11.     fclose($sock);
     
  12. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    Во, ну и круто.