2014-02-20 2 views
0

У меня есть сценарий, который я нашел, что запросы SRCDS gameservers и выводит информацию, такую ​​как имя хоста, IP, подключенные игроки и т. Д. (Примечание, я отредактировал его, чтобы он отображал только подключенных игроков и карту) Мне нужен сценарий сначала выполнить ping-сервер, чтобы проверить, находится ли он в сети или нет, а затем продолжить запросы.PHP Gameserver Query

PHP скрипт

function source_query($ip){ 
$cut = explode(":", $ip); 
$HL2_address = $cut[0]; 
$HL2_port = $cut[1]; 

$HL2_command = "\377\377\377\377TSource Engine Query\0"; 

$HL2_socket = fsockopen("udp://".$HL2_address, $HL2_port, $errno, $errstr,3); 
fwrite($HL2_socket, $HL2_command); 
$JunkHead = fread($HL2_socket,4); 
$CheckStatus = socket_get_status($HL2_socket); 

if($CheckStatus["unread_bytes"] == 0)return 0; 

$do = 1; 
while($do){ 
    $str = fread($HL2_socket,1); 
    $HL2_stats.= $str; 
    $status = socket_get_status($HL2_socket); 
    if($status["unread_bytes"] == 0){ 
      $do = 0; 
    } 
} 
fclose($HL2_socket); 

$x = 0; 
while ($x <= strlen($HL2_stats)){ 
    $x++; 
    $result.= substr($HL2_stats, $x, 1);  
} 

// ord (string $string); 
$result = str_split($result); 
$info['network'] = ord($result[0]);$char = 1; 
while(ord($result[$char]) != "%00"){$info['name'] .= $result[$char];$char++;}$char++; 
while(ord($result[$char]) != "%00"){$info['map'] .= $result[$char];$char++;}$char++; 
while(ord($result[$char]) != "%00"){$info['dir'] .= $result[$char];$char++;}$char++; 
while(ord($result[$char]) != "%00"){$info['description'] .= $result[$char];$char++;}$char++; 
$info['appid'] = ord($result[$char].$result[($char+1)]);$char += 2;   
$info['players'] = ord($result[$char]);$char++;  
$info['max'] = ord($result[$char]);$char++;  
$info['bots'] = ord($result[$char]);$char++;  
$info['dedicated'] = ord($result[$char]);$char++;  
$info['os'] = chr(ord($result[$char]));$char++;  
$info['password'] = ord($result[$char]);$char++;  
$info['secure'] = ord($result[$char]);$char++;  
while(ord($result[$char]) != "%00"){$info['version'] .= $result[$char];$char++;} 

return $info; 
} 

Показать код

include 'status.php'; // name of file including above script 
$q = source_query('ip:port'); // replaced with real IP address and port 
echo "Players: " .$q['players']; 
echo "/" .$q['max']; 
echo "<br>"; 
echo "Map: ".$q['map']; 

Для уточнения: этот сценарий штрафа в возвращении подключенных в данный момент игроков и текущую карты воспроизводимого работает, когда сервер находится в сети. Когда сервер находится в автономном режиме, он загружается некоторое время, а затем просто печатает

Players:/
Map: 

Я хочу, чтобы сервер заранее пинговал. Если он-лайн он делает, как и выше, но если он отсутствует, я хочу, чтобы это эхо «автономно», удалите

Players:/
Map: 

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

ответ

1

Это, скорее всего, не ускорит ход событий, но, вероятно, лучше, чем то, что у вас есть по крайней мере. Тем не менее, я хочу отметить, что в руководстве по PHP говорится об этом применительно к использованию unread_bytes: Note: You shouldn't use this value in a script. Вы также можете уменьшить таймаут (последний параметр) при вызове fsockopen.

function ping($host) 
{ 
    exec(sprintf('ping -c 1 -W 5 %s', escapeshellarg($host)), $res, $rval); 
    return $rval === 0; 
} 

$HL2_command = "\377\377\377\377TSource Engine Query\0"; 

if(!ping($HL2_address)) 
{ 
    return 0; 
} 

$HL2_socket = fsockopen("udp://".$HL2_address, $HL2_port, $errno, $errstr,3); 

Показать код

include 'status.php'; // name of file including above script 
$q = source_query('ip:port'); // replaced with real IP address and port 

if($q === 0) 
{ 
    echo "Offline"; 
} 
else 
{ 
    echo "Players: " .$q['players']; 
    echo "/" .$q['max']; 
    echo "<br>"; 
    echo "Map: ".$q['map']; 
} 
+0

Это работает, если сервер находится в Интернете или существует. Однако это не так, как указано выше. Если сервер отключен, он пытается запросить его, что занимает много времени. Вот почему я хочу включить функцию ping, чтобы проверить, находится ли она в сети или нет до того, как будут сделаны какие-либо запросы! – JakeGriffin

+0

@JakeGriffin Что такое ваше определение «offline»? Весь сервер отключен? Конкретный порт недоступен? Вы получаете пустой ответ? Возможно, что определение того, является ли сервер «автономным», может занять немного времени. Вот почему я предложил снизить тайм-аут. –

+0

«offline» Я имею в виду все вышеперечисленное. Например, если я выбрал 192.168.1.1:80, и ничего не было запущено на порту 80, для загрузки страницы в автономном режиме требуется много времени.Было бы нецелесообразно заранее проверять адрес, чтобы проверить, есть ли что-то на самом деле, и отвечать перед тем, как запросить его? Я не знаю, имеет ли это смысл. Кроме того, тайм-аут установлен на 4 секунды, но для загрузки страницы требуется намного больше времени, если он запрашивает то, что не существует/отключено. Взгляните на [это] (http://www.griffingaming.co.uk/test.php) - обратите внимание на то, что для загрузки требуется много времени. – JakeGriffin

1

по manual из fsockopen, особенно для UDP соединений, вы должны рассмотреть, чтобы сделать больше обработок ошибок:

Предупреждения

UDP сокетов иногда по-видимому, открыты без ошибок, даже если удаленный хост недоступен. Ошибка будет только очевидна при чтении или записи данных в/из сокета. Причина заключается в том, что UDP является протоколом «без установления соединения», что означает, что операционная система не пытается установить связь для сокета до тех пор, пока на самом деле не потребуется отправлять или получать данные.