I want to use server time in an php/javascript application. Time to the second is quite important for the app. However there appear to be some discrepancies of up to 3-4 seconds, despite checking the time differences between client and server time.
My angular code is as follows;
// Pre ajax time (so we can see how long it took to get data from server)
var timeElapsed = new Date().getTime();
$http.get('/getServerTime.php')
.success(function (data) {
// Calculate the length of the ajax request in seconds
timeElapsed = new Date().getTime() - timeElapsed;
// Add that to the returned server time to get the current
// server time. (data.date is provided by the getServerTime.php page)
$scope.serverTime = data.date + timeElapsed;
$scope.timeDifference = new Date().getTime() - $scope.serverTime;
});
Theoretically this should work but discrepancies of up to four seconds are occurring.
Any suggestions or code modifications would be gratefully received.
Its not a good idea to mix client and server time at all.
Client time is not reliable at all, since the user can change his time anytime and anyhow he wants. If he feels funny he can make his time 06.06.2066 right now. What would your program do then ? Probably nothing good.
Do not mix these up and the best way would probably be to use the server time -only-
Except you just need the difference of two time points to evaluate a duration. In this case you can use the client-time since for a difference of timestamps the absolute value doesn't matter (2016 or 2066, who cares... 3 seconds are 3 seconds)
Furthermore there is another problem in your code. If you want to "calculate the current server time" by adding the value returned from the server plus the time elapsed since your ajax call - you're missing the delay your request takes to reach the server.
say you send your request at 0ms - the server will get the request at 20ms and put it's current server-time in the response. then your client will get the result at, say, 50ms.
then the calculated server time will be off by 20ms compared to the actual server time.
in the end what you're trying to do seems like a very non-best-practice approach to be fair.
Maybe if you tell us what exactly you want to achieve with this approach we can help you find a better solution
You can configure your server to return it's time in a "Date" header - this is a standard http header - this way you don't need to have a dedicated rest for it:
https://en.wikipedia.org/wiki/List_of_HTTP_header_fields
Even so you will only have the timestamp when the request left the server.
If you have the same problem as me and you need to display the time passed since something started on server - the network latency is not much of an issue here.
For any other usages you will need to let UTC do the work.
Hope it helps.
Related
I'm trying to understand more about long polling to "manipulate" a website in real time, saw some videos and I'm thinking so far:
Say I have an old date that the sql and I make an echo on it. As long polling will know if the old date will not be the same as it will look from time to time according to the setInterval function ...?
Say I want to show publication of a blog in which all text is in mysql, but repende I publish a new publication, and who is on the page at the time, you will see the publication time (not tell me?), Then how one long polling code will know the difference between the old and the new publication? Ate even not to give conflicting or repeating the same date engraved on the sql.
Since your initial question was what the difference between the two techniques is, I will start with this:
AJAX polling
Using AJAX polling to update a page will mean, that you send a request in a defined interval to the server, which would look like this:
The client sends a request to the server and the server responses immediately.
A simple example (using jQuery) would look like this:
setInterval(function(){
$('#myCurrentMoney').load('getCurrentMoney.php');
}, 30000);
The problem with this is, that this will cause a lot of useless requests since there won't be always new things on every request.
AJAX long polling
Using AJAX long polling will mean, that the client sends a request to the server and the server waits for new data to be available before he responds. This would look like this:
The client sends a request and the server responds "irregularly". As soon as the server responds, the client will send a new request to the server.
The client side would look like this:
refresh = function() {
$('#myCurrentMoney').load('getCurrentMoney.php',function(){
refresh();
});
}
$(function(){
refresh();
});
What this will do is just load the getCurrentMoney.php's output into the current money element and as soon as there is a callback, start a new request.
On the server side you usually use a loop. To solve your question how the server will know, which are new publications: either you pass the timestamp of the newest to the client available publication to the server or you use the time of the "long polling start" as indiactor:
<?
$time = time();
while ($newestPost <= $time) {
// note that this will not count as execution time on linux and you won't run into the 30 seconds timeout - if you wan't to be save you can use a for loop instead of the while
sleep(10000);
// getLatestPostTimestamp() should do a SELECT in your DB and get the timestamp of the latest post
$newestPost = getLatestPostTimestamp();
}
// output whatever you wan't to give back to the client
echo "There are new posts available";
Here we won't have "useless" requests.
I have a dashboard page, where I have some time values that come back from the server. These times are in the format: HH:MM:SS (13:05:01, for example). But that value only refresh when then user reloads the page. I would like to do some javascript to keep that value going on... what's the easiest easy to do that? Thanks in advance!
Can you give me a valid reason to spam the servers with requests for time over and over again when the user machine has high probability of having perfectly valid time - is connected to internet and unless user has not messed with it it's correct.
(You might have to offset for zones, not 100% about that)
Downsides of approach to ask server over and over for current time:
You will suffer from latency
You will spam server without valid need
Ability to scale is sinking very fast both by items and users
If you need to check user time matches yours, do a 1 request at the start and then compare times with a bit of offset allowed. If times don't match set the correct time on front from back and display user device time +- whatever the difference was. If they match close enough display user's device time.
Deletes all the negatives. Adds no new negatives.
EDIT upon comment:
Oh, that makes more sense. You can query server on reload but if you expect to reaload a lot (and you need a time to be static after once being set up) you can use localStorage to store it on new browsers or cookies (work for older browsers as well).
For something that is not likely to change I would not query the server again if I don't need to. In case you need / wanna query the server again specifficaly when page loads or reloads you can add this to element on that page onload="myFunction()"
In myFunction handle to call to the back and binding to text of element displaying it.
Personally, I would go about doing it with setInterval, just set it to run the function that updates your time, and set the interval, to 1000 (milliseconds) for it to change every second. You can look Here for more info.
A simple method to measure the roundtip-time of an Ajax request is to measure the time between the start and the end of a request (readyState 4). Many examples exist for this kind of measuring.
But this measurement is not really accurate. The Ajax callback will only be invoked, as soon as it comes up in the browser event loop. Which means that if there is some blocking operation inbetween, the measurement would also contain some client processing time and not the actual server roundtrip-time (server processing time + network time).
I know that this kind of functionality is now available through the Resource Timing API Specification, but at the moment it is not consistently implemented accross all browsers.
Is there any other way to find out the real roundtrip-time or the timestamp, at which the server response is available and waiting for the corresponding callback to execute?
NetworkInformation.rtt
You can use navigator.connection.rtt to obtain the estimated effective round-trip time of the current connection, rounded to the nearest multiple of 25 milliseconds.
const estimated_round_trip_time = navigator.connection.rtt;
console.log(estimated_round_trip_time);
Note: At the time of posting, navigator.connection.rtt is still considered experimental technology. Expect behavior to change in the future, and proceed with caution before using it in your application. See Browser Compatibility.
I'm new to the idea of AJAX as well as caching.
On the AJAX - Send a Request To a Server from W3Schools, it says you should add "?t=" + Math.random() to the end of the URL of the script to run to prevent caching.
On Wikipedia, the simple definition of "cache" is:
In computer science, a cache is a component that transparently stores data so that future requests for that data can be served faster. The data that is stored within a cache might be values that have been computed earlier or duplicates of original values that are stored elsewhere.
But, shouldn't this be better? The script will run faster if the computer already has some duplicate data stored. Also, the first example on the tutorial page, without the addition to the URL, worked fine.
Can somebody please tell me the reason behind using "?t=" + Math.random()?
But, shouldn't this be better?
Yes it's better to have a cache system for perfomance reason, your application pages will load quickly because the elements loaded once will be retrieved without making each time a HTTP request to the server.
Can somebody please tell me the reason behind using "?t=" + Math.random()?
Adding this "?t=" + Math.random() is like renaming the URL of the script each time you reload it. The caching system will see it as a new element and not as an old one he as already stored even if nothing as really changed. So it's forcing to reload the element from the server.
Generally, we may want to do that on elements (like images, scripts) that are often updated. For example, it's the case for a profile picture in a website that a user could change, if the old picture file is in cache, the user will not see the new picture appear immediatly if we don't use that trick of the random number. The user could think his upload didn't work. He would have to empty the cache manually in his browser, which is not always very intuitive.
A second reason could be that it's good to do it while we are developping because we don't need to empty the cache every minutes that our code changes are taken into account...
However don't use this trick on elements you are sure will don't change or very rarely.
The reason behind adding some random element to the end of a web service request like that is because in many cases you want the data to always be fresh. If you are caching it, it is possible the data won't be fresh.
For example, say you have an AJAX request which gives you the current high score of a game. You call it with http://example.com/get_high_score.php. Say it returns 100. Now, say you wait 5 seconds and call this again (or the user refreshes their page). If that request was cached, it may return 100 again. However, in that time, the score may actually now be 125.
If you call http://example.com/get_high_score.php?t=12345786, the score would be the latest value, because it wasn't cached.
url + "?t=" + Math.random() is just one means of doing this. I actually prefer to use a timestamp instead, as that is guaranteed to always be unique.
url + "?t=" + (new Date()).getTime()
On the flip side, if you don't need the data to always be fresh (e.g., you are just sending a list of menu item options which almost never change), then caching is okay and you'd want to leave off the extra bit.
An alternative is to use a timestamp, or design one that changes every few seconds. Although the best method (if you can) is to add entries in the header in your server response to tell the browser not to cache the result.
var t = new Date().getTime();
var t2 = Math.floor(t/10000);
url = target_url + "?t=" + t2;
Although its unlikely in this case, be aware if your site continually generates links to random internal URLs, say through server side code, then it becomes a "spider trap" and crawlers such as search engines get stuck in a loop following these random links around causing peaks in your server load.
I'm trying to get request a json object from the server each 10 seconds using this:
setInterval(function(){
$.ajax({
url: '/',
success: function(data){
//do stuff with data
}
});
}, 10000);
But this isn't very efficient. I know about long-polling, but I don't think it'll make a big difference. I know I will receive new data each 10 seconds, so doesn't that make long-polling the exactly same as setInterval in terms of efficiency?
Is browser-side caching a good solution for this problem?
The JSON object I'll be getting looks like this:
var data = {1: {'user': 'John', 'age': '25'}, {2: {'user': 'Doe', 'age': '30'}}
With this, I want to display data[0].user for a few seconds and after that smoothly change it into data[1].user by using 'fadeOut' and 'fadeIn' and so on until it runs out of users.
I basically want to create a slideshow of the user's usernames.
Would caching be a good solution or should I stick with making ajax calls every 10 seconds? If so, then how would I implement this and if not, what method should I use?
I'm not sure if i explained it good enough, so tell me if something is still unclear.
I would definitely think about caching. Especially if you get sets with a lot more users, making an AJAX request every 10 seconds could easily overload your server. However, if you want to keep it simple, make a request every few minutes instead, to update. Cache the users, have them generated into the javascript code, say users = new Array(user1, user2, ...). You don't really have to keep updating the page if it's not that important, as most users would navigate away within a minute or two anyways. If you have a long list that changes every few seconds, that gives you enough time to not ever have to update using AJAX, and just rely on the server generated list of users.
If not, store the last time you updated the list in a variable, and send the time as an argument to your server when you're updating via AJAX, and then have the server quickly check what new users were added, and send just those. Then, just merge the new array of new servers with the old array. I highly suggest not making a call every 10 seconds for a new name though. Not only will you run up more bandwidth on your server, you will increase the CPU usage when it has to find the next user in the list for you, and then send you that one. For good practice, always let the client do as much of the work as possible, without having lag. There is only one server, but many more clients. Each operation you shift to the clients will save your server hundreds, if not thousands, of operations.
As for long polling vs setInterval, I would recommend setInterval in that case. You can at least send a request with a time argument, specifying the last update time, and thus only needing to send that small portion, instead of the entire data array.
var storage = new Array(user1, user2, ...); //set all your data here, generate it from your server
var lastUpdate = //set the last time you updated it, just create a date variable
function rotateUsers()
{
//do your fade in and fade out here
}
function update()
{
//create a new HttpRequest, and then set the url as "yoursite.com/update?lastUpdateTime="+lastUpdate;
//Take the response data, and merge the new users list with the old one
}
setInterval('rotateUsers()',10000);
setInterval('update()',60000); //update once a minute
Long polling would be better than setInterval(fn,delay) because at least then the server would just send you updated data when it was ready, versus the client making that assumption and then firing off a request for data that may not have changed.
If you have control over client/server tech, you can push data to the client without the need to reconnect the XHR on each push by using WebSockets