jquery/javascript setInterval - javascript

Currently I'm developing a user notification alert message function.
I managed to use setInterval to control my Ajax call (to check if there's any notification msg for the user). But my problem is that I only wanted the notification message only
appear once on the page (Now it displays multiple notification alert msg on the screen). I know that you can use setTimeout to make it only call once but I also needed the page to check if there's a new notification message alert in every 5 min.
Second question is it possible the first round calling the Ajax call instantly and then all other calls every 5 min? Because I wanted the system to check instantly once they logged into the system n then afterward every 5 min.
Here is my code
function getAjaxNotice() {
$.post("/async/getnotification", {},
function(response) {
var notice = $(response);
$("#notices").prepend(notice);
});
return false;
}
setInterval("getAjaxNotice()", 50000);

First of all, you should wrap your initialization code in an onLoad function:
$(document).ready(function() {
// Put all your code here
});
Making it appear once is easy, use .html() instead to set the content rather than add to it:
$("#notices").html(notice);
Third, as a style note, you should not pass a string to setInterval(). Rather, pass a function name:
setInterval( getAjaxNotice, 50000 );
Finally, to make it call the function now, and again after every 5 minutes, use:
// Set the timer
setInterval( getAjaxNotice, 50000 );
// Call it once now
getAjaxNotice();
Also note that 50000 is 50 seconds, not 5 minutes. 5 minutes would be 5 * 60 * 1000 = 300000.

For the first problem, you should be storing the return value from setInterval, and then calling clearInterval(myIntervalId) when you receive an alert.
For the second problem, you can call getAjaxNotice once during onload of the body, and then if no alerts are received, call setInterval at that point.

setInterval's time is in milliseconds.
5 minutes * 60 seconds * 1000 milliseconds = 300000ms
Also, I suggest you pass a function to setInterval not a string, so you can avoid the implicit use of eval.
setInterval(getAjaxNotice, 300000);
To call getAjaxNotice at the start of the page, put it in a ready block.
$(function(){
getAjaxNotice();
});

A couple of things...
setInterval("getAjaxNotice()", 50000);
Is not 5 minutes.
5 minutes = 300000 milliseconds.
and if you want it to run instantly and THEN do it every 5 minutes you can simply do
$(document).ready(function() {
getAjaxNotice();
function getAjaxNotice() {
$.post("/async/getnotification" ,
{},
function(response)
{
var notice = $(response);
$("#notices").prepend(notice);
});
return false;
}
setInterval( getAjaxNotice(), 300000 );
});

In your situation it sounds like you are dealing with a few problems. So using your current approach, you can initially make your ajax call and follow it up with a set timeout:
getAjaxNotice();
setTimeout( "getAjaxNotice()", 300000);
Secondly, ensuring the user received the message only once can be done easily if you have some type of "message confirmed" event. Assume your user could have browsers open on multiple computers, if you make the user click the message or click an ok button, or perform some action to acknowledge they received the message, you can fire off another ajax call to delete that message from the buffer on your server, yet still display it on all open browsers. The local browser would only display it once because you could prevent displaying it client side if the message is a duplicate (based on what ever criteria makes sense for your application)
However, you should look into long polling and COMET, http://en.wikipedia.org/wiki/Comet_(programming). Comet is a concept around pushing notifications to web browsers based on server side events, as opposed to web browsers constantly asking the server for changes.
Due to limitations in web frameworks and browsers, this was accomplished with a few technologies, but long-polling seems to be the most prevalent. HTML5 and websockets are trying to make some changes that could prevent polling all together, but its not readily available yet.
Long Polling, http://en.wikipedia.org/wiki/Push_technology, and COMET based architecture have been used by companies like meebo and facebook. Don't quote me on this but for some reason I'm inclined to believe facebook uses an Erlang based webserver to serve their chat messages. Erlang and NodeJs are just a couple of solutions you can use to build light weight web servers that work well with tons of long polling requests hitting your servers.
You should definitely go read up on all these things yourself as there is a wealth of information available. I have experimented with create a NodeJs server on Amazon EC2, as I'm traditionally a .NET job and don't feel IIS is the right solution for supporting an the long polling features of a .net application which uses long polling, and I have to say I like NodeJs alot. Plus the javascript language is much more familiar to me than my limited knowledge of Erlang.

Related

Javascript timer function

I'm using a timer function to check if the session is valid or not every five seconds.
setInterval(checksession,5000);
function checksession(called_for) {
//alert('check-session')
$.ajax({
type:'POST'
,url:'CheckSession'
,success: validateresult
,data: { antiCSRF : '{{acsrf}}',
session_id: '{{session_id}}'}
//,error: function(){ alert('Session check failed') }
})
}
I would like to know what will happen if I have multiple ajax calls at the same time when the session is checked. Will it be 2 separate threads?
Is this the correct way to check session?
So first off, you're better off (imo) using setTimeout for this rather than setInterval. You really want your next check to happen x seconds after you have the answer from the previous check, not every x seconds regardless (b/c of server lag, latency on the network, whatever). Bottom line, imo it's better to do setTimeout then do another `setTimeout in the ajax callback.
JS is single threaded, so you won't do it in two separate threads, but you can have multiple ajax calls pending at once, which I think is what you mean.
Finally, on "correct". It really depends a bit on what you're trying to accomplish. In general, sessions with sliding expirations (the only real time that any 'check' to the server should matter, since otherwise they can get the expiry once and count the time on the client) are there to timeout after a period of inactivity. If you're having your script 'fake' activity by pinging the server every five seconds, then you might as well just set your expiry to infinity and not have it expire ever. Or set it to expire when the browser window closes, either way.
If you're trying to gracefully handle an expired session, the better way to handle it in Ajax is to just handle the 401 error the server should be sending you if you're not logged in anymore.

how to update chat window with new messages

setInterval(function{
//send ajax request and update chat window
}, 1000)
is there any better way to update the chat with new messages? is this the right way to update the chat using setInterval?
There are two major options (or more said popular ways)
Pulling
First is pulling, this is what you are doing. Every x (milli)seconds you check if the server config has changed.
This is the html4 way (excluding flash etc, so html/js only). For php not the best way because you make for a sinle user a lot of connections per minute (in your example code at least 60 connections per second).
It is also recommended to wait before the response and then wait. If for example you request every 1 second for an update, but your response takes 2 seconds, you are hammering your server. See tymeJV answer for more info
Pushing
Next is pushing. This is more the HTML5 way. This is implemented by websockets. What is happining is the client is "listing" to a connection and waiting to be updated. When it is updated it will triger an event.
This is not great to implement in PHP because well you need a constanct connection, and your server will be overrun in no time because PHP can't push connections to the background (like Java can, if I am correct).
I made personally a small chat app and used pusher. It works perfectly. I only used the free version so don't know how expensive it is.
Pretty much yes, one minor tweak, rather than encapsulate an AJAX call inside an interval (this could result in pooling of unreturned requests if something goes bad on the server), you should throw a setTimeout into the AJAX callback to create a recursive call. Consider:
function callAjax() {
$.ajax(options).done(function() {
//do your response
setTimeout(callAjax, 2000);
});
}
callAjax();

How to reduce time difference between clients receiving data in socket.io?

A node.js project with modules socket.io and express.
Now each client has a canvas, which runs animations on it. When server emit the initiate parameter, the animation can start.
Now the problem is, there is a Time Gap between clients when their animations start. The longer the animation runs, the more obvious the gap would be. The position of the figures would become really different. But what i want is everybody see the same thing on their screen。
Here's how the server deliver the data:
socket.broadcast.emit('init', initData);
socket.emit('init', initData);
The animation function is in the client, it starts when receiving the initiate data from the server.
I'm not sure if it's because the time receiving these data is different in each client.
So how to reduce this gap?
Many thanks.
I think you should try the following: make sure (using onLoad events and collecting that events on server with socket.io) that every clients downloaded animation, and then send signal to start it.
here is a simple formula and routine that works with socket.io, php or anything really.
I used it to fade in a live video stream 10 seconds before it aired. Given the inherent lag and device performance patterns, and wrong time-zones, you can only expect to get about 30ms of precision forward or backward, but to most observers, it all happens "at the same time".
here is a simulation of a server that's about two minutes behind a simulated client (you), and the server wants the client to show a popup in 1.2 seconds:
//the first two vars should come from the server:
var serverWant=+new Date() - 123456 + 1200; // what server time is the event ?
var serverTime=+new Date() - 123456; // what server time is now ?
//the rest happens in your normal event using available info:
var clientTime=+new Date(); // what client time is now ?
var off= clientTime - serverTime; // how far off is the client from the server?
var clientWant= serverWant + off; // what client time is the event ?
var waitFor = clientWant - +new Date(); // how many millis to time out for until event ?
setTimeout(function(){ alert( 'SNAP!' );}, waitFor);
how reliable is this? try changing both "- 123456"s to "+ 12345"s and see if the popup still waits 1.2 seconds to fire, despite not using Math.abs anywhere in the calculation...
in socket.io, you could send the server time and scheduled time to the client for computation in a pre-event:
socket.broadcast.emit('pre-init', {
serverTime: +new Date(),
serverWant: +new Date() + 1200
});
and then use those values and the above math to schedule the animation in a few moments or a few hours as needed, on-demand (yours) to the split second.
You need Dead Reckoning technique in order to simulate client side state as close to real state on server as possible.
You might send state packages to clients periodically, for example every 200ms (5 times a second), and on client side extrapolate from this data.
Additionally to this, you have to remember about different latency for different clients. So as you want to keep same state there is generally two approaches - interpolation (use last known and one before data), or extrapolation (use last known and predict in future based on own latency).
Extrapolation suits better for real-time interactive stuff, but will have problems with error correction - when client will do wrong prediction (object suddenly stopped but based on delay client predicted it still moved).
Interpolation would make everything pretty much delayed and in a past, but will not suffer from errors as there is no predictions. The drawback of this as you need to wait before interpolating amount of time equal to slowest latency user. This means that slower user will force everyone to be slowed down as well.

How to test latency from user to server in browser using javascript?

I want to gather some information using the visitors of my websites.
What I need is for each visitor to ping 3 different hostnames and then save the following info into a DB.
Visitor IP, latency 1,latency 2, latency 3
Of course everything has to be transparent for the visitor without interrupting him in any way.
Is this possible? Can you give me an example? Are there any plugins for jQuery or something to make it easier
EDIT
This is what I have so far jsfiddle.net/dLVG6 but the data is too random. It jumps from 50 to 190
This is going to be more of a pain that you might think.
Your first problem is that Javascript doesn't have ping. Mostly what Javascript is good at is HTTP and a few cousin protocols.
Second problem is that you can't just issue some ajax requests and time the results (that would be way too obvious). The same origin policy will prevent you from using ajax to talk to servers other than the one the page came from. You'll need to use JSONP, or change the src of an image tag, or something else more indirect.
Your third problem is that you don't want to do anything that will result in a lot of data being returned. You don't want data transfer time or extensive server processing to interfere with measuring latency.
Fourth, you can't ask for URLs that might be cached. If the object happened to be in the cache, you would get really low "latency" measurements but it wouldn't be meaningful.
My solution was to use an image tag with no src attribute. On document load, set the src to point to a valid server but use an invalid port. Generally, it is faster for a server to simply reject your connection than to generate a proper 404 error response. All you have to do then is measure how long it takes to get the error event from the image.
From The Filddle:
var start = new Date().getTime();
$('#junkOne').attr('src', 'http://fate.holmes-cj.com:8886/').error(function () {
var end = new Date().getTime();
$('#timer').html("" + (end - start) + "ms");
});
The technique could probably be improved. Here's some ideas:
Use IP address instead of DNS host name.
Do the "ping" multiple times, throw out the highest and lowest scores, then average the rest.
If your web page has a lot heavy processing going on, try to do the tests when you think the UI load is lightest.
With jQuery you could:
$.ajax(url,settings)(http://api.jquery.com/jQuery.ajax/) and take the time from beforeSend and on complete via Date.now(), subtract those times -> then you have the time for the request (not excactly the "Ping" though)
2021:
Tried this again for a React app I'm building. I don't think the accuracy is too great.
const ping = () => {
var start = new Date().getTime();
api.get('/ping').then((res) => {
console.log(res)
var end = new Date().getTime();
console.log(`${end-start} ms`)
}, (err) => {
console.log(err)
})
};
Wrote my own little API, but I suppose there's just way too much going on during the request.
In terminal, I get about 23ms ping to my server.. using this it shoots up to like 200-500ms.

How to capture visitor time on page

I would like to keep track of how long visitors spend reading a page. If they tab away, or minimize the window, time should not count towards the time on page until they look at the tab again.
I assume some combination of javascript and server side work will be necessary.
A couple of issues I'm struggling with:
What's the best way to store this information in the database?
How do I, with Javascript, capture the time on page with a reasonable degree of accuracy? Do I store events like "page loaded", "user idle", "user returned", "page unloaded", and then separately process all the events in the DB to come up with a time on page?
I've put some work into a small JavaScript library that times how long a user is on a web page. It has the added benefit of more accurately (not perfectly, though) tracking how long a user is actually interacting with the page. It ignores time that a user switches to different tabs, goes idle, minimizes the browser, etc. The Google Analytics method suggested has the shortcoming (as I understand it) that it only checks when a new request is handled by your domain. It compares the previous request time against the new request time, and calls that the 'time spent on your web page'. It doesn't actually know if someone is viewing your page, has minimized the browser, has switched tabs to 3 different web pages since last loading your page, etc.
https://github.com/jasonzissman/TimeMe.js
An example of its usage:
On loading your page:
document.onload = function() {
TimeMe.setIdleDurationInSeconds(30);
TimeMe.setCurrentPageName("my-home-page");
TimeMe.initialize();
}
Retrieving time spent on the page, and sending it to your server when the user leaves your page:
window.onbeforeunload = function (event) {
xmlhttp=new XMLHttpRequest();
xmlhttp.open("POST","ENTER_URL_HERE",false);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
var timeSpentOnPage = TimeMe.getTimeOnCurrentPageInSeconds();
xmlhttp.send(timeSpentOnPage);
};
First, you need to detect when a user has moved away from a tab or is inactive. When this happens, start a timer, when they come back, stop the timer. Counting time with setTimeout/setInterval can be innacurate because of blocking, so I made myself an accurate javascript timer based on the actual difference in datetime: https://gist.github.com/4600726
So your code would look something like this:
timer = new Timer;
window.addEventListener('focus', function() {
timer.start();
}, false);
window.addEventListener('blur', function() {
timer.stop();
// send timer.msecs() to the server maybe??
// if so, also call timer.reset();
}, false);
window.addEventListener('beforeunload', function() {
timer.stop();
// send timer.msecs() to the server via jquery post, or better yet websocket
}, false);
Then you can get the elapsed time with timer.secs(). I guess it depends on your preference how often you want to send info to the server. You could do it on blur.
Another option could be to decree that no mouseover means inactivity. Start the timer and then do a setTimeout, then on the window's mousemove event cancel the setTimeout and start another setTimeout , after which you stop the timer.
As far as sending data to the server, I'd probably opt for sending it on blur and of course beforeunload. My preferred method would be with socket.io since it is fast and always connected, so you could use it to track lots of user events in real time, but you could just to an ajax call to your server. If you just send them as mini user sessions, { user: userId, page: pageId, elapsedTime: msecs } then you could then aggregate the data on the server end when you are doing analysis.

Categories