The problem im facing is: I have N IPads which can trigger an event. How to know on server side who did trigger the event first. Languages used for server side is PHP and for client side JavaScript (JQuery). The biggest problem is latency, so simply sending AJAX polling would not work, since i could press button before j but server could get j request before i due to latency. Also saving press time is no optimal since IPads are not synchronized to milliseconds or smaller units. Maybe there is some kind a protocol, which deals with this from which I could get some ideas?
-
1Can you create a javascript date and send it along with the request? You would need to synchronize it to a single time zone, but seems simple enough. – mrtsherman Jan 31 '12 at 22:50
-
2what do you hope to sync that needs this realtime timing? – Joseph Jan 31 '12 at 22:52
-
@mrtsherman you can't guarantee the exact time settings for each device. one will not care what timezone a device is in as long as it shows the correct time (unless there is such a thing as a compulsory time sync mechanism) – Joseph Jan 31 '12 at 22:54
-
You could send an arbitrary Date when the iPads request some page and then a JS would use that as seed for a timer; unless some heavy processing, there would not be a significant delay... and each one would send back the event time using the Date instance created from your Date – Alfabravo Jan 31 '12 at 23:02
-
I could send date and time with request, but IPads have to be synchronized between them selves. The seed idea sounds better, of course the latency of network could make some offsets for time sent back, and in the end time in clients could differ a bit from servers time depending on the time the request went back to each of them, theoretically. Maybe there is algorithm how to guarantee that the seed will be synchronized between all clients. The thing is, clients have to be synchronized really good. – Jānis Gruzis Feb 01 '12 at 13:13
-
@Joseph I need to sync devices for the game. Its like quiz show only buttons are replaced with IPads, first who drags the button, gets turn to answer. So in my opinion, the biggest problem is, how to know which person dragged the button first in case when they both dragged it with really short time interval. – Jānis Gruzis Feb 01 '12 at 13:56
-
games have always suffered due to this issue. even though the player fires a shot earlier than the other, he gets killed due to latency. let me guess, the questions are "pulled" from the server right? it's not just when the players push the buttons, it's also who gets and reads the questions first. – Joseph Feb 01 '12 at 20:21
-
@Joseph Yes, but all the devices will be in same room, so everyone will be able to read the question, because it will be shown on one screen. – Jānis Gruzis Feb 02 '12 at 16:28
1 Answers
here are 2 methods you can use to check latency.
then you can calculate the user's request arrival time
actual time of request = request arrival time - latency
request arrival time must be server time (when the request arrives on the server) side so we don't need to sync units. but the latency data must come from client along with the request data. you must create a client-side script to poll and calculate average latency times.
the first method is taken from a question here in stackoverflow. this one uses ajax. this is the most accurate i have ever searched, with less than 10ms deviation from actual. what it does is it calls (via ajax) a page of your server (the "/" url in the example is your web root)
advantage: we use jQuery ajax
.success()
which fires an event after the reply is received but before loading the reply data (thus request size doesn't matter)disadvantage: ajax does not cross-domain (without aid). but if you have your own server, no problems.
the second one is taken from here and i modified it a bit. this originally was created as a server tester to test if the server is still there.
advantages: cross-domain (we use
img = new Image()
"image preloader" method)disadvantage: the internet speed. payload size (in this case, an image) and internet speed will matter since we only use
.onLoad()
which fires after the content has loaded.
there will be a deviation of about 200-400ms on this one, depending on the image size.
//this is a static class. values are preserved. do resets before and after use.
var ping = {
//the sample image. make it as small as possible like 1 x 1 px black and white.
//we are only testing ping, not download times
//replace with your own image on your server since this link will die soon
picture: "http://205.196.122.17/vh8cvmdtgfsg/8nsd22kphe1fz5w/spacer.bmp",
//placeholder for test subject
pictureFrame: null,
//timer
timer: null,
reset: function(){
//clear timeouts and timer
clearTimeout(ping.timer);
ping.timer = null;
//clear the picture frame
ping.pictureFrame = null;
},
//start ping function
init: function() {
//reset
ping.reset();
//get time before request
var preSess = new Date();
var preTime = preSess.getTime();
//append current timestamp so request won't be from cache
var pictureUri = ping.picture + "?time=" + preTime;
//create placeholder
ping.pictureFrame = new Image();
ping.pictureFrame.onload = function() {
//get time after load
var postSess = new Date();
var postTime = postSess.getTime();
var requestTime = postTime - preTime;
alert("Ping took "+requestTime+"ms");
//reset
ping.reset();
};
//triggers loading
ping.pictureFrame.src = pictureUri;
//set maximum timeout (in ms) before we declare domain not there
ping.timer = setTimeout("ping.failed()", 60000);
},
//time-out reached
failed: function() {
//reset
ping.reset();
//alert what happened
alert("Ping took too long");
}
};
ping.init();