I am new in javascript and php. I am creatng an admin panel in which I have an option for the user to play game. But the issue is, every game have a specific time period say 30 mins. So, what I want is that if a user have started the game, the count down must be started and if user once switch from that page to another page, still the counter must be counting and after 30 mins it should end the game.
For example I am on http://www.examplec.com/Game1 my count down of 30 min will start. If I switch from that page to another like http://www.example.com/order then the counter should still count the total time and when its expired, end it and send query to database.
Kindly reply if anyone know the solution. I have already find a solution using session but I want more efficient solution. One more thing a single user can play more than 1 game.
when your game start set a session of current time like this
$_SESSION['game_start_time'] = strtotime(date('d-M-Y g:i:s A')); // it will give you complete current timestamp.
and now check it on every page by including
if(isset($_SESSION['game_start_time']))
{
$game_start_time = $_SESSION['game_start_time'];
$current_time = strtotime(date('d-M-Y g:i:s A'));
$time_diff = $current_time - $game_start_time;
if($time_diff>(30*60))
{
//expire 30 minutes your code is here
}
else
{
// action if require to do when below 30 minutes of game start.
}
}
What you could do is create a table to keep track of the time, this is not the most efficient way but it would be secure.
So create a new table called gametrack with the following fiels:
id
userid
gameid
timestarted
etc
so when a user starts a game you insert a record with user info.
Next you need to edit the game page. In the game page you could place a jquery code to request for update on the time.
function gameStatus(){
$.ajax({
url: 'status.php?gid=[GAMEID]',
success: function(data) {
if(data == 1) {
//DO SOMETHING, REFRESH THE PAGE, STOP THE GAME ETC
}
}
});
}
setInterval("gameStatus()",10000);
the code above would request status.php every 10 seconds, you need to pass the gameid to the file and assuming that the user is registered you can use session to get user info and return 1 if 30 mins has passed.
You can mix this solution with Satish's Answer to use Sessions instead of Databases and still get a live count down with the jquery code above.
You can try this with localStorage
When you want to set variable:
var name = "value";
localStorage.setItem("someVarName", name);
And in any page (like when the page has loaded), get it like:
var Name = localStorage.getItem("someVarName");
Browser compatibility caniuse.com/namevalue-storage
Demo
Related
I made a premium membership system to my discord bot, but the time starts to be minus a certain time, so I want to delete the data from the database when the time I set with ms expires. I tried something like that but it didn't work
I save the data as follows;
Looks like you are setting the interval to an incredibly long time. It looks like you are storing the specific time you want the function to run. You'll probably want to do something like this:
let interval = sure - new Date();
if(interval < 0) { // this expiration date already passed
interval = 0;
}
setInterval(function() {
db.delete(` ... `);
db.delete(` ... `);
}, interval);
However! If you do all this multiple times (like inside the 'message' handler like you're doing right now), you're gonna have a memory leak. Make sure you are setting the intervals only once.
Also, if your program crashes, you'll have to set up all the intervals again at startup.
If I was making something like this, I would instead make a cron job to check only once per day to delete all the expired members, instead of using setIntervals.
I am developing a numbers game where users will buy numbers and after 2 days winners will be drawn.
I am using PHP for the backend and jQuery for the frontend.
My problem is when drawing occurred user on different browser can't see same numbers, these draw numbers are being generated by PHP.
I was thinking maybe I can build these game by PHP and Javascript but it looks not easy. Can you guys please suggest some alternative? How can I improve this code to show the same number on the different browser?
I have the idea that it is not possible to generate a random number for each request. Maybe I can save the number in the database and then get this number in PHP such that the number will be unique for each request.
The actual issue is to create the same content for each user in different browsers. Any help would be really appreciated.
Javascript:
var myTimer = setInterval(checkDrawDate, 1000);
function checkDrawDate() {
var today = new Date();
var date = today.getFullYear()+'-'+(today.getMonth()+1)+'-'+today.getDate();
var time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
var dateTime = date+' '+time;
var x = new Date(dateTime);
var y = new Date("{{$drawDate}}"); //this is laravel variable which contain drawdate e.g. 2017-07-05
if(x >= y){
drawNumber();
}
}
function drawNumber(){
$.get("{{ route('ajaxcomparepowerball') }}",{'gameId': gameid}, function(res){
$('#mybets').html(res.html);
});
}
PHP:
public function ajaxDrawNumber(Request $req){
return rand(0,49);
}
A Cron Job will be needed to implement this functionality. As you are drawing a number on particular time (after $drawDate in your case). So the cron job will execute once in day, check whether $drawDate for each game is today or passed. If condition true, $drawDate <= now, call a function to generate random draw number rand(0,49) and save it to database corresponding to gameid of matched games(having $drawDate <= now).
By doing this, a lot Javascript work will be reduced. In JS, then need to hit an ajax request with gameid to fetch record having draw number for particular game from database. If record not found, it means random number not drawn yet.
I think you are using Laravel, so to schedule tasks in laravel visit here.
Here some possible solutions.
If you need the same data modified for users in real time I think the best option is WebRTC, quick start here. And here a simple example sending strings in real time between clients.
If you also need interaction server to client you could use server-sent events.
You could perform a bidirectional communication between browser and a server using WebSockets. You can send and receive event-driven responses. Using a database you could communicate two clients.
The easiest is using a database to store the information and perform ajax to send data to the server (and database) and server-sent events to send data to the clients.
Basic Server-sent event example:
Javacript:
var evtSource = new EventSource("myserver.php");
evtSource.onmessage = function(e) {
// listening for new messages here
alert(e.data)// e.data is mynumber
}
Php (myserver.php)
<?php
header('Cache-Control: no-cache');
header("Content-Type: text/event-stream\n\n");
while (1) {
//perform a query in your database with your driver
$result = mysql_query("SELECT mynumber FROM mytable WHERE user = 1");
$row = mysql_fetch_assoc($result);
echo $row['mynumber'];//<-- sending mynumber to client
ob_end_flush();
flush();
sleep(1);// <-- this is every second, but you could fire this with ajax or some other event.
}
This code send a number from server to a client that is listening. If a user made a change, one possibility is that client send an ajax to update some value in the database. So, at the same time, the ajax server could send this as an update to clients listening. In that way the whole process is completed.
I think all you need is this. Call a function in every, say 5 seconds or less and fetch data from server and update it in the page.
window.setInterval(function(){
updateNumber();
}, 5000);// set for every five seconds
function updateNumber(){
//ajax code to fetch live data and append the data in the numbers container
}
And dont forget to cross check the data before saving the numbers in the server.
Hope it helps.!!!
To save and maintain users state, key value store like Aerospike can be used. It is very easy to save and retrieve data in key value store. In above case we just have to generate a unique key using gameId, userId and date. And save user's data against the unique key.
To get started with Aerospike php client following is Aerospike php client
If data is present against the unique id for that particular user just return it, else create the new random number save it against the unique key and return it. Please be careful while creating unique key. Instead of using server side date-time please send date in ajax call request so there will not be any issue with time zone. It will be always user's timezone and there will not be any issue if server is in different timezone and user is in different timezone.
function drawNumber(){
$.get("{{ route('ajaxcomparepowerball') }}",{'gameId': gameid,'date':user-timezone-date}, function(res){
$('#mybets').html(res.html);
});
}
Here "user-timezone-date" should be fix date format like 'MM-dd-yy' which will indicate the same day. hours or seconds should not be included while generating unique key otherwise at the time of retrieving the user's state; generating particular unique will be changed every hour or every second and whole purpose of of doing this will be shattered.
I am new to StackOverFlow so I am not able to comment on the answers. In case of corn job as well we have to be careful with time-zones if server and users are in different time zones. Otherwise user's will see different random number before user's day is complete. Please improve answer by commenting on it and suggestions are always welcome.
Im working on kinda program which main part is to count the time which user spent on website, and then to save recorded time in database.
How it works: on the page user has button to start recording his time, then he gets moved to another page, where he can save his time. Saved time is being sent to the php file (through ajax), and then php file puts value in database for current user.
THE PROBLEM is that after 60 seconds of recording time - table in database starts from scratch (00:00:00). For example: if user has already recorded 30 seconds (00:00:30), then he runs the script, records 40 seconds more, and then instead of 00:01:10 in database his score is clear (00:00:00)
Details below.
MySQL Table - type: time
//JS
$("#stopTimer").click(function(event) {
var time = event.timeStamp;
$.ajax({
type: 'POST',
async: true,
url: 'timer.php',
data: {time: time}
});
});
//PHP
$time = ($_POST['time']/1000);
$stmt = $db->prepare("UPDATE members SET timeOnline = timeOnline + '$time' WHERE memberID = :memberID");
$stmt->execute(array(':memberID' => $memberID));
If you want to add seconds to a TIME column use + INTERVAL x SECOND:
UPDATE members
SET timeOnline = timeOnline + INTERVAL :time SECOND
WHERE memberID = :memberID
Try it in another way.
Keep one extra column named start_time . When user first press this button store current time on that.
When user browse in different pages, just calculate the time difference in timeOnline .
It will also be simpler.
I am trying to add on a script of mine that is checking some factors for multiple websites a COUNTDOWN that will let the user know, live, how many hours/minutes/seconds will remain until script finishes the task. I need to do this to a php script of mine. But really don't know where to get started. I only know that is possible to COUNT the time of a script HAD BEEN executed with microtime() function. I tried searching lots of scripts here, but I barely found smth related to some dynamic progress bars (but not very well explained) and nothing to a dinamic countdown timer that can countdown execution time of script.
Would be much appreciated any help related this issue (links, functions, scripts...)
Without knowing what your script does, there is no way to know ahead of time how long it will take to run. Even if we did know what it does, to know the precise time it will take to run really is not possible. If this is all within the same session you could put "% complete markers" at certain main points in your script. I do this in a few places. It makes a nice progress bar and I also show the total elapsed run time as well. If something like this is what you want then read on...
(this is using a jQuery UI progress bar)
If your script is a loop and each iteration is basically doing the same thing then the growth of the progress bar will be pretty fluid. If this isn't the case, and your script does many things very fast, then a few things very slow, then you bar will be like pretty much all Windows progress bars :) It could get to a certain point very quickly then hang there for a while.
Not at my PC so I'm sure there are typos below but you should be able to get the point. Hope this helps...
Something like this would be in your long running script...
$_SESSION["time_start"] = microtime(true);
$_SESSION["percentComplete"] = 0;
... some of your php script ...
$_SESSION["percentComplete"] = 10;
... some of your php script ...
$_SESSION["percentComplete"] = 20;
... some of your php script ...
$_SESSION["percentComplete"] = 30;
... etc ...
$_SESSION["percentComplete"] = 100;
die();
?> //end of your php script
but if your long running script is a loop it would be more like this...
$loopCnt = 0;
//your php loop
{
$loopCnt = $loopCnt+1;
//...the meat of your script...
$_SESSION["percentComplete"] = round(($loopCnt/$totalRecordCount)*100);
}
$_SESSION["percentComplete"] = 100;
die();
?> //end of your php script
Then on the page the user interacts with an ajax ping could be setup to check the value of $_SESSION["percentComplete"] every couple seconds or so and make the progress bar grow based off the result. Something like...
function checkScriptProgress()
{
$.ajax({
url: "checkScriptProgress.php",
type: 'get',
cache: false,
success: function( data, textStatus, jqXHR) {
//(1) MOVE THE PROGRESS BAR
//if you are using a jQuery UI progress bar then you could do something like...
//jQuery("#yourProgressBar").progressbar( "option", "value", data.progress );
//if you are using HTML5 progress bars it would look like...
//var pBar = document.getElementById("yourProgressBar");
//pBar.value = data.progress;
//(2) UPDATE ELAPSED TIME
//if you want to display the total run time back to the user then use: data.totalRunTime
//(3) If report is not finished then ping to check status again
if (data.progress < 100) setTimeout("checkScriptProgress();", 1000); //check progress every 1 second so the progress bar movement is fluid
})
});
}
Then the checkScriptProgress.php file would look something like...
<?php
header('Content-Type: application/json');
$time_end = microtime(true);
$time = $time_end - $_SESSION["time_start"];
echo '{"progress":'.$_SESSION["percentComplete"].',"totalRunTime":'.$time.'}';
die();
?>
Before any progress has been made, an initial estimate requires an estimate of how long each action will take to complete, and the number of actions to perform. (This formula assumes that processing is not done in parallel)
final_timestamp = start_timestamp + (number_of_actions * average_duration_per_action)
Record progress, including number of actions completed and total time spent so far. This allows you to update the estimate.
updated_final_timestamp = start_timestamp + (current_timestamp - start_timestamp) / (num_action_completed / num_actions_total)
You will never be able to determine the duration of any execution task before starting the task. Thats when artificial intelligence comes to be a part of your algorithm. You will need to train your algorithm with a large set of data that will make it possible to Predict the duration of the task.
For example you can create an INSERT statement of a major part of your application and then start counting the time using microtime(). When the insert statement is done with any other pre processing, you will save this data as a training data.
In your application now .. When someones tries to use the same Process. You will say it will take about 33 seconds for example. and you use your javascript code to control the dynamic progress bar to be in 100% state after 33 seconds!
Code Example:
<?php
//** this is done in development phase **//
function MyFunction($arg1, $arg2){
// calculate the current time.
$startTime =microtime(true);
// My Process in here ......
$final_time = microtime(true) - $startTime;
// Save final time for future usage.
// Repeate the step 100 times with random data
}
// Now you can pre calculate the average of this task
// based on the previous training data.
function MyFunction($arg1, $arg2){
// Get avarege executing time for this..
// Tell the user that this function will take ? amount of time.
}
?>
This method is more reliable and efficient than counting the time while doing the task.
You will never need to calculate the time in the middle of the task because you already did that.
You will never need an ajax that will hit your server every second
Your Progress bar is moving smoothly because you know the time it takes.
However, if you just need a dynamic progress bar that changes with every line of code you will need to manage your javascript inside your PHP code.
Finally, the last method will cause a problem if one line is taking more amount of time than other lines. Your progress bar may reach %90 in 3 seconds. and stop for 10 seconds in that state until it moves to 100%, which seems unreal.
You will need to calculate the time before you start
You will need to calculate the time after you finish
You will need to calculate the difference between the two timestamps.
And you will increase you progress bar Un dynamically.
I basically have a page that when loads, reads an Oracle SQL table for a specific record id that may not currently exist at the point as it may take up to a minute to insert this specific record into the table.
Based on this, I need a means of showing a "Loading Image" while it waits for the record to exist, so has to wait. Once it does, I want to remove the loading image and present the user with the record details. I am using Oracle Application Express 4.2 for this.
My question is not so much the loading/hiding of the image but how to continually check for the record within the Oracle table, during page load.
Either I receive the record successfully and then hide the image or say after 1 minute, I dismiss the checking of the record and present the user with a message indicating that no record was found.
Sorry for my english. I will try help you.
Make your "Loading image" always visible on the page. There is no need to show it on load, you only need to hide it at proper moment.
Add Application Process to your application. Name it for example "GET_MY_ROW". Process must check your event, and return some flag, for example 1 or 0.
Example:
declare
l_cnt number;
begin
select count(*)
into l_cnt
from table1 t
where id = 12345;
if l_cnt > 0 then
htp.p(1);
else
htp.p(0);
end if;
end;
3.3 Add javascript code as page load event (for example by Dynamic Actions):
Javascript code:
var myInterval = setInteral(function {
var get = new htmldb_Get(null,$v('pFlowId'),'APPLICATION_PROCESS=GET_MY_ROW',$v('pFlowStepId'));
get.GetAsync(function(pRequest) {
if (pRequest.readyState == 4) {
if (pRequest.responseText == 1) {
alert('Record loaded successfully');
// add function call, hiding your "Loading image" here
clearInterval(myInterval);
}
};
});
get = null;
}, 5000); //check every 5 seconds
setTimeout(function() {
alert('Sorry, no record was found. Try again later.');
clearInterval(myInterval);
}, 60000); // fail after 1 minute
Since NoGotnu already answered, I'll put this here:
Is there any reason for the procedure to be called through a job? Is it the only way to create the required record? Is the job called anywhere else? Why not call the procedure directly when the required page has been submitted and show the loading icon there? When it finishes, the user knows it has finished. That would involve a lot less fiddling around as you can make apex show a processing graphic on page submit. You could then just inform the user on the other page that the process has not been ran yet and they'd have to do that first.
Secondly, while NoGotnu's answer will work, I'd like to point out that in apex 4.2 you should use the apex.server namespace instead of the never documented htmldb_Get construction. apex.server.process is a clean implementation of the jQuery ajax setup.
NoGotnu's code translated:
apex.server.process( "GET_MY_ROW"
, null
, { dataType: text
, success: function(pData){
if (pData == 1) {
clearInterval(myInterval);
alert('Record loaded successfully');
};
}
}
);
The call doesn't really need to be async though, but ok.
Another option would be to implement a "long poll" instead of firing the ajax event every 5 seconds. A long poll will just initiate a call to the server and wait for a response. As long as the server is busy, the client will wait. To achieve this you could use dbms_alert, as suggested in Waiting for a submitted job to finish in Oracle PL/SQL?
You'd signal an alert in the plsql code of the job, and in the ondemand process code register an interest in the alert and use waitone/any with a 60 second timeout. Presto long poll.