0

I use this jQuery code to display a Session Timeout window ( http://jsfiddle.net/xHEF9/515/ ) The problem is when a user stay longer in a page to work then the timoutValue, the window will popup.

I need to find a way to reset the session on each activity the user performs on the page.

I would appreciate any help with that.

Here is the code I use:

<script type="text/javascript">        //<![CDATA[
         var timeout=<%#(int)HttpContext.Current.Session.Timeout%>*60*1000;
          //var timeout=2*60*1000;

         var uservar = "<%# Session["userID"]%>";
         $(window).load(function () {

             (function (a) {
                 jQuery.sessionTimeout = function (b) {
                     function f(a) {
                         switch (a) {
                             case "start":
                                 window.onbeforeunload = null;
                                 redirTimer = setTimeout(function () {
                                     window.location = d.redirUrl
                                 }, d.redirAfter - d.warnAfter);
                                 break;
                             case "stop":
                                 clearTimeout(redirTimer);
                                 break
                         }
                     }

                     function e(b) {
                         switch (b) {
                             case "start":
                                 //window.onbeforeunload = null;
                                 dialogTimer = setTimeout(function () {
                                     a("#sessionTimeout-dialog").dialog("open");
                                     f("start")
                                 }, d.warnAfter);
                                 break;
                             case "stop":
                                 clearTimeout(dialogTimer);
                                 break
                         }
                     }
                     var c = {

                         message: "Your session is about to expire.",
                         keepAliveUrl: "default.aspx",
                         redirUrl: "<%# Page.ResolveClientUrl("~/LogOut.aspx?user=")%>"+uservar,
                         logoutUrl: "<%# Page.ResolveClientUrl("~/LogOut.aspx?user=")%>"+uservar,
                        warnAfter: 9e5,
                        redirAfter: 12e5
                    };
                    var d = c;
                    if (b) {
                        var d = a.extend(c, b)
                    }
                    a("body").append('<div title="Session Timeout" id="sessionTimeout-dialog">' + d.message + "</div>");
                    a("#sessionTimeout-dialog").dialog({
                        autoOpen: false,
                        width: 400,
                        modal: true,
                        closeOnEscape: false,
                        open: function (b, c) {
                            a(".ui-dialog-titlebar-close").hide()
                        },
                        buttons: {
                            "Log Out Now": function () {
                                window.location = d.logoutUrl
                            },
                            "Stay Connected": function () {
                                //this event is triggered when the user tries to leave the page
                                window.onbeforeunload = confirmExit;
                                a(this).dialog("close");

                                a.ajax({
                                    type: "POST",
                                    url: d.keepAliveUrl
                                });
                                f("stop");
                                e("start")
                            }
                        }
                    });
                    e("start")
                }
            })(jQuery)
            $(document).ready(function () {

                $.sessionTimeout({
                    warnAfter: timeout-(60*1000)
                    ,redirAfter: timeout
                });
            });
        });//]]>  
</script>
RobM
  • 3,588
  • 2
  • 19
  • 14
Steve
  • 1,028
  • 7
  • 25
  • 42
  • Rather than re-create the wheel, you can use this technique: http://stackoverflow.com/questions/3877821/how-to-keep-alive-a-users-session-while-they-are-posting-on-a-forum – RobM Aug 10 '13 at 23:17

1 Answers1

3

In short, you could use a variable on the page and update it on activity such as on key presses and mouse clicks. If there has been activity, do a ping to keep the server session alive.

Rather than recreate an entire write up, you can see the technique demonstrated here: How to keep alive a user's session while they are posting on a forum?


EDIT:
To help you out, I've spent a good chunk of time and taken the code you borrowed, substantially modifying and restructuring it so that you should be able to better understand what's going on in the code. This should improve your chances of successfully updating it further. I didn't spend any time optimizing it, but it should work. I've updated the fiddle so you can try it out:

http://jsfiddle.net/xHEF9/555/

and also included the updated code below.

var activityTimer, warningTimer, redirTimer;
var haveNewInput = false;
var inactivityParms = {
    warningMessage: "Your session is about to expire.",
    keepAliveUrl: "/keep-alive",
    redirUrl: "/timed-out",
    logoutUrl: "/log-out",
    activityCheckEvery: 3000, //  3 sec * 1000 ms
    warnAfter: 10000,         // 10 sec * 1000 ms
    redirAfter: 20000         // 20 sec * 1000 ms
};


// Function to check for keyboard input and reset timers if input is detected
function setActivityCheckTimer(activityCheckTimerAction) {
    switch (activityCheckTimerAction) {
        case "start":
            activityTimer = setInterval(
                function () {
                    if (haveNewInput == true) {
                        pingServerToKeepSessionAliveAndResetTimers();
                        haveNewInput = false;
                    }
                },
                inactivityParms.activityCheckEvery);
            break;
        case "stop":
            clearTimeout(activityTimer)
    }
}

function setWarningTimer(warningTimerAction) {
    switch (warningTimerAction) {
        case "start":
            warningTimer = setTimeout(
                function () {
                    $("#sessionTimeout-dialog").dialog("open");
                    setActivityCheckTimer("stop");
                    setRedirTimer("start");
                },
                inactivityParms.warnAfter);
            break;
        case "stop":
            clearTimeout(warningTimer)
    }
}


function setRedirTimer(redirTimerAction) {
    switch (redirTimerAction) {
        case "start":
            redirTimer = setTimeout(
                function () {
                    window.location = inactivityParms.redirUrl
                },
                inactivityParms.redirAfter - inactivityParms.warnAfter);
            break;
        case "stop":
            clearTimeout(redirTimer)
    }
}


function AppendWarningMessage() {
    $("body").append('<div title="Session Timeout" id="sessionTimeout-dialog">' + inactivityParms.warningMessage + "</div>");
    $("#sessionTimeout-dialog").dialog({
        autoOpen: false,
        width: 400,
        modal: true,
        closeOnEscape: false,
        open: function () {
            $(".ui-dialog-titlebar-close").hide()
        },
        buttons: {
            "Log Out Now": function () {
                window.location = inactivityParms.logoutUrl
            },
            "Stay Connected": function () {
                $(this).dialog("close");
                pingServerToKeepSessionAliveAndResetTimers();
            }
        }
    });
}

function pingServerToKeepSessionAliveAndResetTimers() {
    setRedirTimer("stop");
    setWarningTimer("stop");
    setActivityCheckTimer("stop");
    $.ajax({ type: "POST", url: inactivityParms.keepAliveUrl });
    setActivityCheckTimer("start");
    setWarningTimer("start");
}

function DetectInputEvents() {
    $(document).keydown(function () {
        haveNewInput = true;
    });
}

(jQuery);

$(document).ready(
    function () {
        AppendWarningMessage();
        DetectInputEvents();
        setActivityCheckTimer("start");
        setWarningTimer("start");
    }
);
Community
  • 1
  • 1
RobM
  • 3,588
  • 2
  • 19
  • 14
  • Thank you for this quick answer. I looked at the code, I just don't know how it fits into my code here. I have to reset the timeout variable somehow. – Steve Aug 11 '13 at 11:23
  • @Steve, do you understand how your current code works? or did you just borrow a snippet from somewhere? Your current code is more sophisticated than this concept. I'm glad to try and help -- just need to understand where you're at. – RobM Aug 11 '13 at 16:09
  • Yeah, I took that snippet from somewhere, I just got the project not too long ago to add this. Not the best with Javascript. – Steve Aug 11 '13 at 20:38
  • See update in the answer. Enhanced your existing with the new functionality you want, restructured and made more readable to help you maintain / enhance. – RobM Aug 17 '13 at 17:51
  • I used this solution while back. Whilst on the whole it's great it does have one problem. If the user opens the site in two different tabs then even if they are active on one tab the other will still log them out. – Chris Nevill Jan 27 '15 at 11:30
  • One solution is to use localstorage.... this requires HTML5 support After setting haveNewInput to false I set a local storage version of have new input if (typeof (Storage) !== "undefined") { localStorage.haveNewInput = true; } else { // No Web Storage support.. } Then bind to the storage event $(window).bind('storage', function (e) { haveNewInput = true; }); – Chris Nevill Jan 27 '15 at 12:20
  • OK there's more to it than that... of course if something else is using local storage on your page you're going to want to make sure it's picking up the right event.. Also need to close any warning windows if they've already opened.... – Chris Nevill Jan 27 '15 at 12:55