Our site has ifame links to different content sites which are used to do online exams
Some exams in the content pages are running 3+ hours
Also exam guard is there for prevent the users doing other stuff while doing the exams
The problem is that once user completed the exams over 3+hrs and come to the parent site (our site)
It has session time out issue in parent page, (Parent site session time out is set to 180min )
As a solution for this we have implemented following JQuery
var to;
$(document).ready(function () {
to = setTimeout("TimeOut()", 10000);
});
function TimeOut() {
$.ajax({ type: "POST",
url: "KeepAliveDummy.aspx", success: function () {
to = setTimeout("TimeOut()", 10000);
}
});
};
Now the problem is that if one user open Parent site and go away it will keep the session unwantedly,
Any suggestion for capture the idle time?
We can use "mousemove" event and see whether the user is active or not.
I have used the below code to test whether the user idle time reached the Maximum Idle time.
function checkIdleTimeOut() {
userIdleTime++;
if( userIdleTime >= maxIdleTime ) {
alert("Reached max User Idle Time");
clearInterval(intvl);
}
$("#output").html( "userIdleTime: " + userIdleTime );
}
I have provided a sample demo, where the max idle time is set to 5 seconds.
Demo at JSFiddle Demo
Related
I am working on a chat system that should trigger an AJAX request whenever the user is inactive for a certain amount of time. I tried to solve it in JavaScript only, but always failed when trying to set back the inactive clock whenever user gets active. Is there any way to achieve this functionality?
As a possible option I identified HTML5 Web Workers. But a created worker cannot access the DOM what I need to do for processing the response of the AJAX request. To bypass this, the worker can post some kind of messages to the main thread, but there I lost the overview completely.
At the moment, I have three relevant code elements that should be able to interact with each other.
Start inactive clock (starts when user is inactive, should trigger AJAX request after some time, but should be able to be stopped by stop inactive clock function):
function startInactiveClock() {
var waitingTime;
var waitStart = performance.now();
// waiting time limit set to 30 seconds
while (waitingTime < 30000) {
// unfortunately kills the web browser
waitingTime = performance.now - waitBegin;
}
triggerAJAXRequest();
}
Trigger AJAX request (should be able to access DOM):
function triggerAJAXRequest() {
$.ajax({
...
success: function(data, status, xhttp) {
response = data;
var newChatMessage = '<div class="ChatMessage">' + response + '</div>';
$("#chatHistory").prepend(newChatMessage);
},
...
});
$("#userInputTxt").focus();
}
Stop inactive clock (starts when user is active, should be able to stop the start inactive clock function):
function stopInactiveClock() {
// do something to stop the inactive function counter
}
You should instead use window.setTimeout.
So you could start the timeout when the inactive period is met and then check again within the timeout so that you are sure the user has been inactive and then trigger the ajax function.
A new page is created on my website, website.com/NewPage
I want the video on this page to start in 20 seconds of the page being created.
At the moment, I have a setTimeout function that waits 20 seconds then starts the video. The problem with that is the 20 second timer starts when EACH USER connects. My goal is to have the website start the video 20 seconds after the page is created, for everyone. Here is an example:
User A enters website.com/NewPage within 3 seconds of the page being created.
User B enters website.com/NewPage within 15 seconds of the page being created.
5 seconds after User B connects, User A's video starts.
User B is at 5 seconds and has to wait 15 seconds for the video to start.
My goal is to get it so that the video starts for everyone at the exact same time, as long as they joined before 20 seconds (Nobody else can join after 20 seconds).
So even if User B joined late, It will start at the exact same time for everyone.
It has to be coordinated on the server. You tagged this with long-polling, so I suppose that's the server communications technique you are using. When the first long-polling connection is opened for a new page, then start a timer on the server.
Since you are sharing a timer among different users, I think you need to maintain the timer in the backend. And in the front-end JavaScript, maintain a separate timer for each user (on their local browser).
Say, your front-end code maybe:
var timer = null;
document.onload = function() {
$.ajax({
url: '/server/timer',
type: 'get',
data: {userName: 'user A'}
}).done(function (res) {
if (res.remaining && res.remaining >= 0) {
alert('Hi, please wait for ' + res.remaining + ' seconds to start playing video');
timer = setTimeout(function() {
// play the video
}, res.remaining * 1000);
} else {
alert('Sorry, you cannot watch the video now');
}
});
}
In your backend code, maintain the API /server/timer to make sure the countdown is the same for every user.
Say I've a browser extension which runs JS pages the user visits.
Is there an "outLoad" event or something of the like to start counting and see how long the user has spent on a page?
I am assuming that your user opens a tab, browses some webpage, then goes to another webpage, comes back to the first tab etc. You want to calculate exact time spent by the user. Also note that a user might open a webpage and keep it running but just go away. Come back an hour later and then once again access the page. You would not want to count the time that he is away from computer as time spent on the webpage. For this, following code does a docus check every 5 minutes. Thus, your actual time might be off by 5 minutes granularity but you can adjust the interval to check focus as per your needs. Also note that a user might just stare at a video for more than 5 minutes in which case the following code will not count that. You would have to run intelligent code that checks if there is a flash running or something.
Here is what I do in the content script (using jQuery):
$(window).on('unload', window_unfocused);
$(window).on("focus", window_focused);
$(window).on("blur", window_unfocused);
setInterval(focus_check, 300 * 1000);
var start_focus_time = undefined;
var last_user_interaction = undefined;
function focus_check() {
if (start_focus_time != undefined) {
var curr_time = new Date();
//Lets just put it for 4.5 minutes
if((curr_time.getTime() - last_user_interaction.getTime()) > (270 * 1000)) {
//No interaction in this tab for last 5 minutes. Probably idle.
window_unfocused();
}
}
}
function window_focused(eo) {
last_user_interaction = new Date();
if (start_focus_time == undefined) {
start_focus_time = new Date();
}
}
function window_unfocused(eo) {
if (start_focus_time != undefined) {
var stop_focus_time = new Date();
var total_focus_time = stop_focus_time.getTime() - start_focus_time.getTime();
start_focus_time = undefined;
var message = {};
message.type = "time_spent";
message.domain = document.domain;
message.time_spent = total_focus_time;
chrome.extension.sendMessage("", message);
}
}
onbeforeunload should fit your request. It fires right before page resources are being unloaded (page closed).
<script type="text/javascript">
function send_data(){
$.ajax({
url:'something.php',
type:'POST',
data:{data to send},
success:function(data){
//get your time in response here
}
});
}
//insert this data in your data base and notice your timestamp
window.onload=function(){ send_data(); }
window.onbeforeunload=function(){ send_data(); }
</script>
Now calculate the difference in your time.you will get the time spent by user on a page.
For those interested, I've put some work into a small JavaScript library that times how long a user interacts with 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 ignore times that a user switches to different tabs, goes idle, minimizes the browser, etc.
Edit: I have updated the example to include the current API usage.
http://timemejs.com
An example of its usage:
Include in your page:
<script src="http://timemejs.com/timeme.min.js"></script>
<script type="text/javascript">
TimeMe.initialize({
currentPageName: "home-page", // page name
idleTimeoutInSeconds: 15 // time before user considered idle
});
</script>
If you want to report the times yourself to your backend:
xmlhttp=new XMLHttpRequest();
xmlhttp.open("POST","ENTER_URL_HERE",true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
var timeSpentOnPage = TimeMe.getTimeOnCurrentPageInSeconds();
xmlhttp.send(timeSpentOnPage);
TimeMe.js also supports sending timing data via websockets, so you don't have to try to force a full http request into the document.onbeforeunload event.
The start_time is when the user first request the page and you get the end_time by firing an ajax notification to the server just before the user quits the page :
window.onbeforeunload = function () {
// Ajax request to record the page leaving event.
$.ajax({
url: "im_leaving.aspx", cache: false
});
};
also you have to keep the user session alive for users who stays long time on the same page (keep_alive.aspxcan be an empty page) :
var iconn = self.setInterval(
function () {
$.ajax({
url: "keep_alive.aspx", cache: false });
}
,300000
);
then, you can additionally get the time spent on the site, by checking (each time the user leaves a page) if he's navigating to an external page/domain.
Revisiting this question, I know this wouldn't be much help in a Chrome Ext env, but you could just open a websock that does nothing but ping every 1 second and then when the user quits, you know to a precision of 1 second how long they've spent on the site as the connection will die which you can escape however you want.
Try out active-timeout.js. It uses the Visibility API to check when the user has switched to another tab or has minimized the browser window.
With it, you can set up a counter that runs until a predicate function returns a falsy value:
ActiveTimeout.count(function (time) {
// `time` holds the active time passed up to this point.
return true; // runs indefinitely
});
I really want to prompt my user to keep the session alive, shortly before it expires.
Yesterday, I asked the question "How can I check if the session is dead, then prompt an alert?" and somebody answered with an AJAX/JSON solution, that made calls every 30 seconds to an ASP page. This didn't work, as the calls to the server kept the session alive - so it would never log out.
I kept reading and came across a similar [SO] question, where somebody suggested using a JS countdown that prompted the user to renew the session, 5 minutes before the session is due to expire.
This is what I have done so far but:
The function startMainTimer does not seem to be keeping the time because I did not receive an alert when the timer was due to alert.
The $('body').mousedown() feature doesn't work as it should. It works but if a user clicks a link, the mousedown function works but doesn't follow the link after the function has run.
Here’s the code:
<script>
$(document).ready(function() {
$.ajax({ // get session expiration value e.g. 60
type : 'GET',
url : '../getSessionValue.asp',
dataType : 'text',
success : function(data) {
if (data != '') {
var newSessionValue = data - 5
startMainTimer(newSessionValue * 60000); // deduct 5 minutes, convert to mSeconds & call startNewTimer()
}
}
});
$('body').mousedown( function() { // if user clicks anywhere on page call ajaxRenewSession() function
ajaxRenewSession();
});
$('#userButtonRenewSession').click( function() { // if user clicks continue browsing button
ajaxRenewSession();
});
});
function startMainTimer(newSessionValue,restart) {
if (restart == 'yes') {
clearInterval(interval);
}
var counter = 0;
var interval = setInterval(function() {
counter++;
if (counter == newSessionValue) {
alert("Your session is about to expire!");
clearInterval(interval);
}
}, 1000);
}
function ajaxRenewSession() { // AJAX the server to renew session, get session timeout value and then reset JS timer
$.ajax({
type : 'GET',
url : '../renewSession.asp',
dataType : 'text',
success : function(data) {
if (data != '') {
var newSessionValue = data - 5
startMainTimer(newSessionValue * 60000, 'yes');
}
}
});
}
</script>
Can anybody help me rectify these problems?
The thing with mouseup seems to work, I tested it on stackoverflow.com. However, it may not work in some cases, e.g. if the user presses a link, drags it and then drops it. In this case, no event was raised for me.
Another thing: You will have to clear the main timer at the beginning of startMainTimer because otherwise, everytime the user clicks somewhere, an additional timer would be started.
And you know that the last call of startMainTimer misses a parameter?
i have a problem.
I am working on a chatting application. I want to kill the session if user closes the browser window without logging off. I used 'beforeunload' function but it also fires when a postback event is fired so it's not good for me.
Please help if anyone have any idea about it.
If you use polling to get the chat data, you should kill the session if you don't get a polling request from the client for a given time.
Client:
setInterval (pollData, 10000); /* poll for new data each 10 seconds */
Server:
if (clientX.LastPollTime is over 30 seconds ago) {
clientX.killSession();
}
I suggest you to use the Alexanders approach, but In most cases setting interval time wont alone solve this problem. Because the user may be idle for some time and it may exceed the timeout period.
In order to avoid this, yo need to add one more condition over this.
if the user is idle for the timeout period then Just make an AJAX request to server and update the client status as idle.
this will avoid logging off the session if the user is idel for certain time.
And you can terminate the session if the server didnt recieve any response from client in a specified time and the status is not updated to idle (during browser close or any application hangups).
yup dear, it is okey, but in second thing as you specified that that server didn't receive any response, in my code server only checks the application session and it will find it so it will work. what i want that if the user not log off then the page is killed and after that how can we call any ajax or xmlhttp request from client side to set the application session to offline.
so please guys tell me something this is the only thing is not going well. and thanx for your response.
As you said the event window.onbeforeunload fires when the users clicks on a link or refreshes the page, so it would not a good even to end a session.
However, you can place a JavaScript global variable on your pages to identify actions that should not trigger a logoff (by using an AJAX call from onbeforeonload, for example).
The script below relies on JQuery
/*
* autoLogoff.js
*
* Every valid navigation (form submit, click on links) should
* set this variable to true.
*
* If it is left to false the page will try to invalidate the
* session via an AJAX call
*/
var validNavigation = false;
/*
* Invokes the servlet /endSession to invalidate the session.
* No HTML output is returned
*/
function endSession() {
$.get("<whatever url will end your session>");
}
function wireUpEvents() {
/*
* For a list of events that triggers onbeforeunload on IE
* check http://msdn.microsoft.com/en-us/library/ms536907(VS.85).aspx
*/
window.onbeforeunload = function() {
if (!validNavigation) {
endSession();
}
}
// Attach the event click for all links in the page
$("a").bind("click", function() {
validNavigation = true;
});
// Attach the event submit for all forms in the page
$("form").bind("submit", function() {
validNavigation = true;
});
}
// Wire up the events as soon as the DOM tree is ready
$(document).ready(function() {
wireUpEvents();
});
This script may be included in all pages
<script type="text/javascript" src="js/autoLogoff.js"></script>
Let's go through this code:
var validNavigation = false;
window.onbeforeunload = function() {
if (!validNavigation) {
endSession();
}
}
// Attach the event click for all links in the page
$("a").bind("click", function() {
validNavigation = true;
});
// Attach the event submit for all forms in the page
$("form").bind("submit", function() {
validNavigation = true;
});
A global variable is defined at page level. If this variable is not set to true then the event windows.onbeforeonload will terminate the session.
An event handler is attached to every link and form in the page to set this variable to true, thus preventing the session from being terminated if the user is just submitting a form or clicking on a link.
function endSession() {
$.get("<whatever url will end your session>");
}
The session is terminated if the user closed the browser/tab or navigated away. In this case the global variable was not set to true and the script will do an AJAX call to whichever URL you want to end the session
This solution is server-side technology agnostic. It was not exaustively tested but it seems to work fine in my tests
PS: I already posted this answer in this question. I am not sure I should answer multiple questions that are similar or post a reference?
If you have control of sessionID cookie, just set its lifetime to 0, that makes the session die on browser close. The lifetime of the session on the open window can be controled from the server side storing the time last seen in the session and checking
if(isset($_COOKIE[session_name()])) {
setcookie(session_name(), $_COOKIE[session_name()], 0, "/"); // die # browser close
}
if(isset($_SESSION['last_time'])){
if( ( time() - $_SESSION['last_time'] ) > 300 ){ // 5 minutes timeout
// here kill session;
}
}
$_SESSION['last_time'] = time();
In the client side you can use the Daniel Melo's answer. I'm using it with one small change:
function endSession() {
// $.get("<whatever url will end your session>");
// kill the session id
document.cookie = 'MYOWNSESSID=; path=/';
}
The only pending matter is that i can't wireup events to input type[buttons] yet, i have made it with raw code, but the all thing works.