0

Okay so here it is.

The code below is my player counter for a game called Minecraft. It connects to a server and brings back 2 values. 1) The number of current online players and 2) the maximum number of player slots.

Then it stores these two variables in to SQL against the server so that I may use them anywhere on the website like: 'Player: 40/100'.

Now the problem is that it takes far too long for one server to reply that it drops out. 8 - 10 servers are updated but the rest are left. What would be great is a method of starting the process, getting 1 ip, get the results, store the results, close the process and repeat. This does them all on one execution.

The perfect script for my needs would:

1) Open a connection to IP #1 allowing 5000ms for a connection
2) Get the data from IP #1 allowing 5000ms
3) Store the data in SQL
4) Close the connection to IP #1
5) Open a connection to IP #2 allowing 5000ms
6) repeat and so on...

The big question: is there a way to get my server to run this check for a few servers at the same time but starting from ((max_id - min_id) / 2).

So it can do 1000 servers in the same time it takes to do 500 as one script stars from id 1 and the other starts from id 500.

Look forward to some awesome replies :)

Thanks!

  <meta http-equiv="refresh" content="180"/>
<?php

if ($_SERVER['SERVER_ADDR'] != '::1'){
echo"You are not authorised to execute this script";
}else{

           include('../config.php');

    set_time_limit(0);        
    class MinecraftQuery 
    {
        public static function query($address, $port, $timeout) 
        {
            $socket = @fsockopen($address, $port, $timeout);

            if (!$socket) {

             echo("Error.");
             mysql_query("UPDATE servers SET cur_players='0' WHERE ip='".$address."';");

            }else{

            fwrite($socket, chr(254));

            $response = "";

            while(!feof($socket)) $response .= fgets($socket, 1024);

            //$result = array();
            $response = str_replace(chr(0),"",$response);
            $response = substr($response, 2);
            $query = preg_split("[".chr(167)."]", $response);

            //$result['hostname'] = ($query[0]);
            $result ['Players'] = (int) $query[1];
            $result['/'] = (int) $query[2];

            echo($query[1]."/".$query[2]);
            mysql_query("UPDATE servers SET cur_players=".$query[1].", max_players=".$query[2]." WHERE ip='".$address."';");

            }

        }
    }

              $servers = mysql_query("SELECT server_name, port, ip FROM servers where enabled = 1 AND active= 1;");
              $num_rows = mysql_num_rows($servers);

            if ($num_rows > 0) {
                while ($serv = mysql_fetch_array($servers)) {
                echo(''.$serv['server_name'].' : ');
                MinecraftQuery::query($serv['ip'], $serv['port'], 2);
                echo('<br /><br />');

                    }
                }
                header('Location: player_count.php');
                }
?>

Edited by mmcdonald: Changed my code

2
Contributors
12
Replies
13
Views
5 Years
Discussion Span
Last Post by pritaeas
Featured Replies
  • 1

    Lol, thanks, but I was trying to get the higher level picture (not a description of the source). On rereading I think I got it. I would probably run a master script, calling a single script for each IP address you want to check, and leave a time out in … Read More

0

It's not actually resolved but I didn't expect a reply so I saw that as the only way of closing it :3

0

The fastest you can execute tasks in the schedular is 1 minute. I need the function above executed every 1 - 10 seconds

0

Whilst I have the attention of a genius poster ( ;) ) could I please ask your advice on the code below. It's supposed to find the lowest id and then run the process, then add 1 to the id, see if that new id exists and then run the process for that new id. BUT if the id doesnt exist it goes back to id = 0 and then speeds through numbers. Could you add the if id exists part to this for me please?

    <?php
/*
if ($_SERVER['SERVER_ADDR'] != '::1'){
echo"You are not authorised to execute this script";
}else{
   */
           include('../config.php');

    // Identify the last IP that was checked, then use that to find the next one to check using previous id + 1
    class MinecraftQuery 
    {
        public static function query($address, $port, $timeout) 
        {
            $socket = @fsockopen($address, $port, $timeout);

            if (!$socket) {
             // If an error occurs, make current_players = 0, then crry on to next id
             mysql_query("UPDATE servers SET cur_players='0' WHERE ip='".$address."'");
             echo('
            <script type="text/javascript">
            window.location.replace("player_count2.php?prev_id='.$cur_id.'");
            </script>
            ');

            }else{

            fwrite($socket, chr(254));

            $response = "";

            while(!feof($socket)) $response .= fgets($socket, 1024);

            //$result = array();
            $response = str_replace(chr(0),"",$response);
            $response = substr($response, 2);
            $query = preg_split("[".chr(167)."]", $response);

            //$result['hostname'] = ($query[0]);
            $result ['Players'] = (int) $query[1];
            $result['/'] = (int) $query[2];

            echo($query[1]."/".$query[2]);
            // After writing current players and max players to SQL, carry on to next id
            mysql_query("UPDATE servers SET cur_players=".$query[1].", max_players=".$query[2]." WHERE ip='".$address."'");
            echo('
            <script type="text/javascript">
            window.location.replace("player_count2.php?prev_id='.$cur_id.'");
            </script>
            ');
            }

        }
    }         


              $min_server1 = mysql_query("SELECT MIN(id) FROM servers");
              $min_server = mysql_fetch_array($min_server1);
              //echo $min_server['0'];

              $max_server1 = mysql_query("SELECT MAX(id) FROM servers");
              $max_server = mysql_fetch_array($max_server1);
              //echo $max_server['0'];

              $prev_id = $_GET['prev_id'];

                $cur_id = ($prev_id + 1);

              // If we've done the last server... go back to the first'
             if (($cur_id) >= $max_server['0']){
            echo('
            <script type="text/javascript">
            window.location.replace("player_count2.php?prev_id='.($min_server['0'] - 1).'");
            </script>
            ');
                }

              $sql="SELECT id, ip, port FROM servers WHERE id = ".$cur_id."";
              $serv_query = mysql_query($sql);
              $serv = mysql_fetch_array($serv_query);

              if ($serv['id'] == null){
                // If the id doesnt exist - skip to the next one
            echo('
            <script type="text/javascript">
            window.location.replace("player_count2.php?prev_id='.$cur_id.'");
            </script>
            ');
              }else{
                // if the id does exist, complete the query
              echo("".$serv['ip']."<br />");
              MinecraftQuery::query($serv['ip'], $serv['port'], 5);
                    }

?>
0

I need the function above executed every 1 - 10 seconds

You could create a script that would trigger itself after it has handled one. Triggering the same script over and over may seriously impact your server.

As for the other item. Why don't you use a last updated timestamp. You can easily select the oldest record, and you will not have the issue of missing id's.

If you want to check if an id exists, just use a select query.

Edited by pritaeas

0

now the last updated timestamp isn't a bad idea! Sorry about my stupidity - I started teching myself PHP a few weeks back and I'm yet to book a course ;)

I was originally thinking of something along the lines of:

          $prev_id = $_GET['prev_id']; 
          $cur_id = "SELECT id FROM servers WHERE id > ".$prev_id." ORDER BY id ASC LIMIT 1";

but your timestamp idea is pretty genius :P

If I was to do it by timestap I could then select 10 id's that haven't been processed in the past 2 minutes and limit the execution to 10. Then get the next 10 and so on...

I'm still conviced that I'm doing this entierly wrong :/

0

Sure :)

1) Connect to DB. Get the lowest id and the highest id from table 'servers'
2) Get the lowest id and find the ip and port from that row
3) run the IP and Port through the function : MinecraftQuery
4) store the results of that function
5) Go to the next highest id in the servers table
6) If step 5 is greater than the highest id then start fro the lowest id
7) if step 5 isn't greater than the highest id, run the current id through the function MinecraftQuery.

Therefore one page load completed the function for one id.

Something like :

Set the current id as $cur_id
When you've completed this go to:

this_file.php?next_id=($cur_id +1)

Then use $_get['next_id'] to do the next row and so on.

But I need to ensure that A) the id exists and B) it goes back to the lowest id when the cycle reaches the highest id.

1

Lol, thanks, but I was trying to get the higher level picture (not a description of the source). On rereading I think I got it.

I would probably run a master script, calling a single script for each IP address you want to check, and leave a time out in it. If it completes successfully, update a timestamp so you can determine how long ago it's values were read. If it fails you could choose to do retries, or mark it as offline for a while.

Votes + Comments
thanks for everything :)
This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.