-1

So I'm making a gaming where 2 people play a game, report their scores on the website, and the winner gets credited. Now I want to add a feature where if one person reports a result and the opponent fails to report his own result within 5 minutes, the website will automatically credit the person who reported the result.

Currently, I have coded a countdown timer in PHP and Javascript (and I prefer to do the countdown in Javascript and call the PHP function after the time elapse but it looks like I can't execute PHP code within Javascript but I would like to do this if possible).

I have equally written the countdown in PHP but it looks like PHP can't run in the background, so it's not updating the balance even after the time elapse.

Here's the PHP countdown as an example of what I want to do.



    <?php
    
    // Set the date we're counting down to
    
    $countDownDate =  strtotime('Dec 25, 2020 15:37:25')  * 1000;
    //Get current date
    
    $now =  time()  * 1000;

        // Find the distance between now an the count down date
        
        $distance = $countDownDate - $now;

        // Time calculations for days, hours, minutes and seconds
        $days = floor($distance / (1000 * 60 * 60 * 24));
        $hours = floor(($distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
        $minutes = floor(($distance % (1000 * 60 * 60)) / (1000 * 60));
        $seconds = floor(($distance % (1000 * 60)) / 1000);

        // Output the result 
        echo days + "d " + hours + "h " +
            minutes + "m " + seconds + "s ";

        // If the count down is over, update user balance.
        if ($distance < 0) {
            $mysqli->query("UPDATE users SET bal=bal+50");
        }
    
   ?>

The problem that this code doesn't update the balance in real-time after the time elapsed. It updates the balance each time the page is reloaded and keeps updating the balance non-stop. WHEN I change the if the part to if($distance ==0) then it will not update at all because PHP is not doing a background check to know when the counter reaches zero and update the balance.

If you understand what I want to do please suggest how I can do this checking and auto-updating. I will also appreciate the sample code.

Thank you.

Felibrain
  • 9
  • 3
  • 1
    javascript runs on the user computer, php is run before dispaly on the server you have to use ajax to call the php function, in its own php. – nbk Oct 27 '20 at 21:58
  • Please can you show example code for calling php from Ajax using Jquery? – Felibrain Oct 28 '20 at 01:01
  • see for example https://stackoverflow.com/questions/16707648/using-jquery-ajax-to-retrieve-data-from-mysql – nbk Oct 28 '20 at 08:38

1 Answers1

0

This is a fairly tricky concept so a few bits to put together, but common and doable. There's a better but more complex way, and an easier hack. I'll explain both.

  1. The "running in the background" bit there are a couple of moving bits:

a) You need to have a process constantly running. While most people will say you need NodeJS or similar, there is no reason why you can't have a PHP script running constantly in the background - what you need to watch for is if the process dies, you need something to restart it (actually, exactly like NodeJS uses pm or systemd to restart - do the same thing with PHP). You script will just constantly "loop" (see below!) looking for work to do.

b) My preferred method, though, if to have a "cron" running every 5 minutes that executes a script, and that script has a timer that loops but will end the loop after 5 minutes and then exit. New process starts. If you do this, you need to factor overlap or minor gaps.

  1. The "loop" mentioned above must not burn your CPU, so you need to handle receiving messages in the right way. Ideally this needs to be ran by a queue, but there are other options.

a) Use a queue system such as RabbitMQ + deal letter queue (although we've moves to AWS SQS as we're hosted on AWS and that allows delayed messages) that holds the message and delivers after 5 minutes. Your script above will be listening for the message.

b) If you don't want to set up a queue, as you know the minimum time is 5 minutes, you could use the "5 minute cron" method and look for messages on start. If there is a message, "sleep" until that message should be processed, process it and look for the next one. If no messages, exit and the cron will repeat in 5 minutes. (Note: sleep is not recommended in a normal PHP script as it holds open HTTP processes, but for a single running background process like this, it's perfect).

  1. Realtime feedback is another thing you can hack, or do correctly.

a) The correct way is to have another constantly running script that accepts socket connections, and JS will connect to the socket. PHP can be used very well for sockets, but NodeJS here does have much better support and you'll find easier. Start the socket server script, use Socket.io or similar in Javascript and connect to the socket server. When you update a score, push the result to the correct client.

b) The easier way is a polling system. Have JS poll the server regularly to see if there are updates. (Socket.io has a fallback to polling as well). This adds more strain on your server, but much easier to set up.

Robbie
  • 17,605
  • 4
  • 35
  • 72
  • Thanks but this sounds so complex. No other simple way to handle what I need? – Felibrain Oct 28 '20 at 01:02
  • "Simple" not that I can think of. There are lots of different approaches but all will need a background process, a queue process and a communications process. – Robbie Oct 28 '20 at 05:16
  • Thanks. But do you know if I can use cron job for this in anyway? Someone also mentioned calling the php function through Ajax as soon as the time elapse but I'm not sure how. – Felibrain Oct 28 '20 at 14:07
  • On the client (browser) use Javascript and "setTimeout" for the required length of time. After the setTimeout, call the server through javascript using AJAX (Google it - there are lods of examples such as https://dev.to/nikola/making-ajax-calls-in-pure-javascript-the-old-way-ed5). This way, the client gets their update on time. Bad news is that it's less reliable and you also need to control against mis-use, but for a starting position it's fine and will do what you need. – Robbie Oct 28 '20 at 21:55