Button click timing a php game - php

I would like to put the 1/1000 second when a button is clicked into a session variable - $_SESSION['Click'] or $_COOKIE['Click']
echo '<img src="./cat.jpg" width="'.$imgwidth.'" height="'.$imgwidth.'">';
The site is called again and the new level is built.
The 1/1000 second when the level is built shall be stored in another session variable $_SESSION['Begin']
Then $_SESSION['TimeNotMeasured'] += $_SESSION['Begin'] - $_SESSION['Click'] or $_COOKIE['CLick']
What would be the solution to get and store the exact time of click?
I finished the Game and it works - but I need a much better solution to measure the time between the moment when the level is finished and the milliseconds or seconds until the next level is built and ready.

You're talking about things that happen in the browser:
Clicks.
Levels that finish.
You therefore have to measure these things in the browser, not in PHP. You could for instance use performance.now(), like so:
const t0 = performance.now();
doSomething();
const t1 = performance.now();
console.log(`Call to doSomething took ${t1 - t0} milliseconds.`);
After you've timed it you can send the information back to the server, with a delay and store it there.

Related

PHP script continuing to run after page close [initiated from AJAX]

Everything I google tells me this should not be happening, however it is.
I'm building a migration tool to build a 'master database'. I have an admin panel, only accessible to a few select people. There is a merge button that starts an AJAX call to run the migration php function. I'm not positive how long this script takes considering I'm still developing it but none the less I'm expecting a minimum of 20 minutes once pushed to production and populated with the production database. I do NOT need a lecture on best practices telling me not to do it via a GUI. This will become a cron as well, however I want to be able to induce it manually, if the admin desires.
So here's my process. The migration function immediately closes the session session_write_close() allowing me to run multiple php scripts simultaneously. I do this because I start a setInterval that checks to see a session variable. This is my 'progress' which is just an int on what loop iteration I'm on. In my migration script I open sessions, add 1 to that int, and close the sessions again. I do this at the end of each loop.
By doing this I have successfully created a progress for my AJAX. Now I noticed something. If I start my migration, then close out of my tab - or refresh. Once I reload the page my progress continues to grow. This tells me that the migration script is still executing in the background.
If I close 100% out of my browser, or clear my sessions I no longer see progress go up. This however is not because the script stops. This is because my progress indication relies on sessions and once I clear my sessions or close out my browser my session cookie changes. However I know the script is still running because I can query the database manually and see that entries are being added.
NOW to my question:
I do NOT want this. If my browser closes, if I press refresh, if I loose connection, etc I want the script to be TERMINATED. I want it to stop mid process.
I tried ignore_user_abort(false); however I'm pretty sure this is specific to command line and made no difference for me.
I want it to be terminated because I'm building a 'progress resume' function where we can choose where to resume the migration progress again.
Any suggestions?
UPDATE:
I didn't want to go this route but some solution I just though of is I could have another session variable. And it's my 'last time client was validated' which could be a timestamp. In my javascript, on the client side, every like 30 seconds I could hit a php script to 'update last time client was validated'. And in my migration function at the beginning of each loop I could check to make sure that timestamp isn't like 60 seconds old for example. If it IS 60 seconds old, or older, I do a die thus stopping my script. This would locally mean 'if there is no client updating this timestamp then we can assume the user closed out of his browser/tab/refreshed'. And as for the function I can ignore this check if in command line (cron). Not the ideal solution but it is my plan B
I am, and did, go with the solution to ping from the client to indicate if the client is still alive or not.
So essentially this is what I did:
From the client, in javascript, I set up a setInterval to run every 1.5 seconds and that hits a php script via AJAX. This php script updates a session variable with the current timestamp (this could easily be a database value if you needed to, however I didn't want the overhead of another query).
$_SESSION['migration_listsync_clientLastPing_'.$decodedJson['progressKey']] = time();
Then, inside my migration function I run a check to see if the 'timestamp' is over 10 seconds old, and if it is I die - thus killing the script.
if(isset($_SESSION['migration_listsync_clientLastPing_'.$progressKey])){
$calc = time() - $_SESSION['migration_listsync_clientLastPing_'.$progressKey];
if($calc > 10){
die();
}
}
I added a 'progressKey' param which is a random number from 1-100 that is generated when the function is called. This number is generated in javascript and passed into both of my AJAX calls. This way if the user refreshes the page and then immediately pressed the button again we won't have 2 instances of the function running. The 'old' instance will die after a few seconds and the new instance will take over.
This isn't an ideal solution however it is an effective one.

Best approach for Server Sent Events with PHP - Performance Advice

I need some advice on performance...
We have a long running PHP script (could potentially take over 10 mins) with progress updates firing back to the UI via Server Sent Events. http://www.html5rocks.com/en/tutorials/eventsource/basics/
Its all running fine, but I'm worried about it hammering the DB.
The rough flow is this;
1) A user goes to the 'publish' page of the app.
2) The UI opens an EventSource stream to a php script that monitors if
a publish is in progress, and reports progress events back if so - checks every
second.
3) If the user initiates a publish, it fires a Ajax call to the long
running php script.
4) The EventSource will then report events back for this publish.
The monitoring is done by storing progress in a mySQL table.
The long running script writes progress to the DB, and the Event script checks this every second.
As I said, it all works, except that it's hitting the database every second for a look up - for every page left open on the publish page.
It is a low user (sub 100 at the moment - but this could increase), low frequency application, so unlikely there will be more than a hand full on that page at the same time, but still - it doesn't take much.
It's all hosted on AWS - micro DB at the moment.
So I suppose my questions are.
1) Hitting the DB every second for each publish page session - is this
bad? should I be worried?
2) What are the alternatives to hitting the DB - write to a file or memory instead ?
(bad if we ever load balance)
3) There is no way to get the PHP event script notified when mySQL
table updates is there?
If I extend it to more then a second, the UI progress is pretty lame (skips too much info).
I could dynamically change the update time. Every second when a publish is in progress, drop down to every 5 or 10 when its not?
Re writing in Node or using a seperate notification server is not really an option - I just want simple progress events for a long running script!!
Any advice much appreciated.
m
1) Hitting the DB every second for each publish page session - is this bad? should I be worried?
This will probably kill your DB quick if your user base grows.
2) What are the alternatives to hitting the DB - write to a file or memory instead ? (bad if we ever load balance)
File would be easiest. Although you could potentially use SQLite and take your primary database out of the equation for this particular issue.
3) There is no way to get the PHP event script notified when mySQL table updates is there?
Sure there is, in a roundabout way. Have the event script listen for changes to a cache file that gets written to whenever your MySQL database updates.

Timer mysql php check

It's bugging me for a day now and I really cant find out, I have a basic login/register page, and when registering, a timestamp is stored in the mysql database(table timer, column cooldown):
$settime = mysql_query("INSERT INTO `timer` (`cooldown`) VALUES(0)") or die(mysql_error());
What I want to do now (I'm creating a browser mmorpg), Is when I do a specific POST request, I want a timer in my database to go off. This timer should be 1 minute, and also be shown for users, like: <?php echo $timer['cooldown']; ?> Whenever the timer is = 0, I can do a specific function again, and the timer will be set to 60 seconds again.
Sorry for the lack of knowledge but I can't find out anywhere how to do this.
What you're trying to do here - a background job - goes against the web development principle of a request-response cycle in the shared-nothing environment of PHP.
But there are several ways to break up the rigid cycle:
If you just need to do some DB updates after 1 minute, you can use MySQL events: http://dev.mysql.com/doc/refman/5.1/en/events.html
If the function you want to call is not running too long, you can check on every user request if there are entries in the timer table that are older than 1 minute.
Create a PHP script that is called by a cron job every minute. It checks if there are unhandled items in the timer table and does something with them.
Create a PHP daemon script that wakes up every minute to check.
If you need to change something on the user page after 1 minute, doing the PHP script call client-side with a JavaScript timeout and AJAX or websockets is the better option.
For displaying the countdown to the user, you have to use JavaScript. If you are using the server-side timer, you can use it just for display purposes, hiding the countdown when it's finished. To work around the "user opens new page before timout is finished" problem, put the data for the remaining seconds in an HTML data attribute where your JavaScript code can read it.

How to create a function like 'build building' like in Ikariam (MMORPGs), that keeps counting when the user isn't on the website

I've been developing games and websites for the past two years, and really love it.
Some time ago I started playing Ikariam (and OGame). These are MMORPGs. You can create your own city by building for example Barracks. BUT, when you click the button to build such thing, it starts counting from for example '10 minutes'.
Then, when you go offline/leave the website, it keeps counting down!
And I was wondering: How/using which coding language do you achieve such thing?
(How do you create a function that keeps getting called via intervals on the server, so the user doesn't need to stay online?)
Thanks in advance,
Dalionzo
P.S. I have a good understanding of JavaScript, PHP, HTML and CSS. I first thought of PHP to do the job, but couldn't figure out how. I also already asked the same question to Ikariam and Gameforge itself, but they said they couldn't provide me that info :(
Rather than constantly running something, just check when the player is online. Like if the current time is after completion time, the building is constructed.
The countdown is pure javascript, no server contact at all. When javascript thinks the countdown has finished, it just refreshes the page which triggersthe server side script that checks construction time.
It's quite simple really, you save the time the countdown started, and then you know that in that time + 10 minutes (600 seconds) the job will be complete. No need to keep pinging a server or anything like this.
IE in PHP:
// On start
$start = time();
$finish = $start + 600;
Save this to a database and then later on you know if time() is between these values it's still building, and it's trivial to work out how much time is left.

PHP: execute script 5 minutes after first script is run

I'm making a PHP site, and I would like to have a script (when you click a button) which adds some info to my MySQL database (I can do this part by myself) and it executes a script 5 minutes later. Maybe it's not difficult, but it's hard to google stuff like this.
Sleep is a VERY bad idea. Client browser would have to wait 5 minutes to finish request!!!
In my opinion it's not possible to do it like you want to.
You should create another script which queries database and checks if there is new data (and on successful fetch does the job). This script should be run by cron every N minutes.
Pretty tough one.
I'd go for something like this:
your original script adds a record to the database, containing its time of execution,
another script contains the action that needs to be taken 5 minutes later - but launches it only if the db record mentioned above contains a timestamp of at least 5 minues ago (hope that's clear enough, I'm having trouble phrasing this)
set crontab to execute the second script every X minutes (perhaps 2).
It won't be 5 minutes EXACTLY, but rather something between 5 and 7 (in case you choose to launch the script every 2 minutes). Would that do?
You could implement a queue in your database, where you add "commands" to be executed, and also store when to execute this command. Then have a cron job that runs every minute and checks said queue to see if it's time to execute a certain command.
If you're on a unix box:
exec("echo 'php script.php' | at now +5 minutes");
Which will schedule the php script.php command to run after 5 minutes.
I'm making a browser-based game and I want it to if someone wants to build a building it takes * minutes and then finishes.
Considering this is your actual goal, I recommend just saving the original building with a timestamp.
I know you tagged your question with PHP, but I don't want to include all the overhead of handling mysql queries in PHP, especially since I don't know how you prefer to execute the queries or what framework you're suing, so here's some pseudocode to handle this "building buildings" task:
build.php
building_type_id = sanitize(POST['id'])
user_id = current_user['id']
query('INSERT INTO buildings (user_id, building_type_id, created_at)
VALUES (' + user_id + ', ' + building_type_id + ', CURRENT_TIME)');
my_buildings.php
user_id = current_user['id']
completed_buildings = query('SELECT * FROM buildings b
LEFT OUTER JOIN building_types t ON b.building_type_id = t.id
WHERE DATE_ADD(b.created_at, INTERVAL t.construction_time SECOND) < NOW();')
under_construction = query('SELECT * FROM buildings b
LEFT OUTER JOIN building_types t ON b.building_type_id = t.id
WHERE DATE_ADD(b.created_at, INTERVAL t.construction_time SECOND) > NOW();')
Hope this helps!
IMHO the best way is: On button click save the job to run in the db with the time it should run. Write a small daemon, fetches every 10/5/2 seconds new jobs which should be executed and executes them.
EDIT: Btw the idea using cron for checking for new jobs to execute, is better, but only if you have a small website and you don't need to do load balancing for the jobs.
The way I would do this is to run a cron job between the two scripts.
the first script sets a value in a database table.
the cron job executes the second script. every minute or what not.
the second script checks for the database value set by script 1 to decide whether to run entirely or not.
I would suggest doing the timer in Javascript rather than PHP.
Put a timestamp in the user's $_SESSION to indicate when they started the event, and then have Javascript call back to the browser after five minutes.
PHP would still need to know the start time (to prevent the user from hacking the game by tweaking the Javascript time-out), but it wouldn't need to actually do any count-down timing or sleeping or anything like that itself.
You could fork the process and in the child fork, do a sleep for 5 minutes before executing your second script. I've tested this and it appears the child process will still execute even after the parent has finished. Something like
//initial code
$pid = pcntl_fork(); //fork the process
if ($pid==0) // if in the child
{
exec("sleep 300; php second_process.php"); //sleep for 5 minutes and execute second script
return; // or exit
}
// rest of initial script...
The "return;" is important as the rest of the script will execute a 2nd time (i.e. in the child) unless it's there.
Someone asked about the purpose of this and your answer was:
"I'm making a browser-based game and I want it to if someone wants to build a building it takes * minutes and then finishes"
You don't actually need to time an execution for this. You can do it all in one run by storing buildStartedAt and buildFinishedAt as part of the building-schema.
Now maybe you want the building to have a nice animation when it finishes, then you just do all of that on the frontend but make sure nothing meaningful can be done with the building if the timestamp is before the buildFinishedAt time in order to a void cheating by potential hackers.
Are you looking for that?
sleep php.net

Categories