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.
Related
When using $http we can set the timeout for it and it will look something like this:
$http.get(url,{timeout: 5000}).success(function(data){});
What is that timeout mean? Is it mean the connection (data download) must be completed within the timeout period? Or it is mean the delay time to receive respond from the server? What would be the best general minimal timeout setting for mobile connection?
If the http request does not complete within the specified timeout time, then an error will be triggered.
So, this is kind of like saying the following to the $http.get() function:
I'd like you to fetch me this URL and get me the data
If you do that successfully, then call my .success() handler and give me the data.
If the request takes longer than 5000ms to finish, then rather than continue to wait, trigger a timeout error.
FYI, it looks to me like AngularJS has converted to using standard promise syntax, so you should probably be doing this:
$http.get(url,{timeout: 5000}).then(function(data){
// successfully received the data here
}, function(err) {
// some sort of error here (could be a timeout error)
});
What is that timeout mean? Is it mean the connection (data download) must be completed within the timeout period?
Yes. If not completed within that time period, it will return an error instead. This avoids waiting a long time for a request.
Or it is mean the delay time to receive respond from the server?
No, it is not a delay time.
What would be the best general minimal timeout setting for mobile connection?
This is hard to say without more specifics. Lots of different things might drive what you would set this to. Sometimes, there is no harm in letting the timeout be a fairly long value (say 120 seconds) in case the server or some mobile link happens to be particularly slow some day and you want to give it as much chance as possible to succeed in those circumstances. In other cases (depending upon the particular user interaction), the user is going to give up anyway if the response time is more than 5 seconds so there may be no value in waiting longer than that for a result the user will have already abandoned.
timeout – {number|Promise} – timeout in milliseconds, or promise that should abort the request when resolved.
Source
Timeout means "perform an action after X time", in JS anyway.
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();
I am studying the ajax long polling but I am confused. what is different in traditional ajax calls and long polling
var lpOnComplete = function(response) {
alert(response);
// do more processing
lpStart();
};
var lpStart = function() {
$.post('/path/to/script', {}, lpOnComplete, 'json');
};
$(document).ready(lpStart);
this example is just calling in recursive manner to the server.. what is different than the traditional call in setInterval..
As the name suggest Long Polling means polling something for a long time.
$.post('/path/to/script', {}, lpOnComplete, 'json');
Here is what the actual process starts, You make an ajax call to some script on server, in this case its /path/to/script , You need to make your server script(php for example) smart enough so that it only respond to request's when required data is available, the script should wait for a specified time period(for example 1 minute) and if no data available upto 1 minute then it should return without data.
As soon as server return something, in your callback function you again make an ajax call to the same script and the server script again continues the process.
Consider a chat application, In conventional way you are polling the server say every 2 second's and the server return's even if no messages are available.If upto one minute server get's no new messages for you, you end up hitting the server 30 times in last one minute.
Now consider Long Polling way, you set your server script to wait for one minute for the new messages. From the client, you make a single ajax call to your script and say no messages are arriving for next one minute, server will not respond until 1 minute. And you have hit the server just one time in last 1 minute. Can you imagine 30 Hit Vs 1 Hit
In theory with setinterval, you could have overlapping processing,
so if one oncomplete handler takes particularly long, it may overlap with the next call, slowing down your system or resolving in unpredictable ways.
by explicitly starting the next poll after the first one has completed, you get less regular calls with the advantage that you're guaranteed to only doing as one unit of work at a time as a byproduct.
There are two ways to do long polling
The setInterval Technique
setInterval(function() {
$.ajax({
url: "server",
success: function(data) {
//Update your dashboard gauge
salesGauge.setValue(data.value);
},
dataType: "json"
});
}, 30000);
The setTimeout Technique
If you find yourself in a situation where you’re going to bust your interval time, then a recursive setTimeout pattern is recommend:
(function poll(){
setTimeout(function(){
$.ajax({ url: "server", success: function(data){
//Update your dashboard gauge
salesGauge.setValue(data.value);
//Setup the next poll recursively
poll();
}, dataType: "json"});
}, 30000);
})();
Using the Closure technique, poll becomes a self executing JavaScript function that runs the first time automatically. Sets up the thirty (30) second interval. Makes the asynchronous Ajax call to your server. Then, finally, sets up the next poll recursively.
With long polling the server does not return unless data is ready, otherwise it holds the network connection open until data is ready, at which stage it can "push" to client as client is already waiting. Wikipedia has a good explanation. http://en.wikipedia.org/wiki/Long_polling#Long_polling. In your example, lponcomplete might not be called for many minutes.
Using constant settimeout type polling means that data that is ready immediately after your first request completes will not be delivered until your next poll, as the server as no connection to the client.
For the server, long polling keeps a socket open for long periods, tying up resource, while repeated short polling causes more network traffic.
Html5 has new stuff coming like websockets to help in this area too, so you might want to read about that also.
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.
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.