This is a followup to an older post of mine about notifying & prompting your users for action once they’ve become idle. I’ve since re-written and abstracted the logic, creating a much more useful & customizable plugin. The main issue with my first implementation, which I’ve addressed in this update, is that the server was never actually polled to maintain an active server-side session during long periods of use. The server-side session might be set to expire after 30 minutes, but a user could be active on your application without a page load for longer than that. As such, following a page load after 30 minutes, the user would (presumably) be prompted to log back in… not a great user experience.

The gist of here is that after a user is idle after a configurable period of time, a div/UI dialog/whatever opens, warning the user that his/her session is about to expire. The user has X number of seconds to click a “resume” link in order to continue their session. If this event is not fired, the user is relocated (configurable) to a page where you’d likely implement server-side code to end their session. Idle state is one without any mouse movement or keypresses, and is detected with Paul Irish’s idleTimer plugin.
- See the Mint.com-style demo, or a demo using the jQuery UI dialog widget.
- Download the source & follow on GitHub.
Polling requests keep the server-side session alive
Polling requests are automatically sent to the server at a configurable interval, maintaining the users session while s/he is using your application for long periods of time. My personal use case for this was an application where the user could write and send emails, but some users took so long to write their message that the server-side session expired before they submitted the form and their e-mail was lost. With ColdFusion and presumably other scripting languages, hitting a CFM file is enough to reset the internal server-side session timer.
Polling is done with a simple setInterval call so requests are not queued per se, but you are protected against failed & built-up requests. If the AJAX request exceeds your configured timeout limit, the request fails, OR the response does not match explicitly what you expect X amount of times, the script aborts itself. This was designed to prevent long-running requests from building up and unnecessarily polling the server when the server isn’t even responding properly. The likely scenario here is if the server goes down while the user is working on your page, or is overloaded and sporadically throwing 500′s or similar.
Usage
Here’s a quick mockup of a demo that opens a UI dialog window after the user is idle for 5 minutes. The user can choose to either keep his/her session alive, or end the session. A live demo of this can be found here. First, markup the dialog’s HTML:
<!-- dialog window markup --> <div id="dialog" title="Your session is about to expire!"> <p>You will be logged off in <span id="dialog-countdown"></span> seconds.</p> <p>Do you want to continue your session?</p> </div>
Next, initiate the UI dialog widget:
// setup the dialog $("#dialog").dialog({ autoOpen: false, modal: true, width: 400, height: 200, closeOnEscape: false, draggable: false, resizable: false, buttons: { 'Yes, Keep Working': function(){ // Just close the dialog. We pass a reference to this // button during the init of the script, so it'll automatically // resume once clicked $(this).dialog('close'); }, 'No, Logoff': function(){ // fire whatever the configured onTimeout callback is. $.idleTimeout.options.onTimeout.call(this); } } });
Finally, init the idleTimeout plugin. We’ll pass in the #dialog div as the first parameter, and the button that will trigger the “resume” functionality as the second parameter. In this demo, the resume logic needs to be bound to the “Yes…” button, which can be found by retrieving the :first button in the div .ui-dialog-buttonpane.
// start the plugin $.idleTimeout('#dialog', 'div.ui-dialog-buttonpane button:first', { idleAfter: 300, // user is considered idle after 5 minutes of no movement pollingInterval: 60, // a request to keepalive.php (below) will be sent to the server every minute keepAliveURL: 'keepalive.php', serverResponseEquals: 'OK', // the response from keepalive.php must equal the text "OK" onTimeout: function(){ // redirect the user when they timeout. window.location = "timeout.htm"; }, onIdle: function(){ // show the dialog when the user idles $(this).dialog("open"); }, onCountdown: function(counter){ // update the counter span inside the dialog during each second of the countdown $("#dialog-countdown").html(counter); }, onResume: function(){ // the dialog is closed by a button in the dialog // no need to do anything else } });
Options
| Parameter | Description | Default |
|---|---|---|
| warningLength | The number of seconds after user is idle to show the logout warning. | 30 |
| keepAliveURL | A url to call to keep the session alive while the user is active. | 30 |
| serverResponseEquals | The response from keepAliveURL must equal this text. | OK |
| idleAfter | The user is considered idle after this many seconds. 10 minutes default. | 600 |
| pollingInterval | A polling request will be sent to the server every X seconds. | 30 |
| failedRequests | The number of failed polling requests until the script is aborted. | 5 |
| AJAXTimeout | The timeout passed to $.ajax in milliseconds. | 250 |
| onResume | A callback to fire when the session is resumed (by clicking the resume link). | function(){} |
| onIdle | Fires when the user becomes idle. | function(){} |
| onCountdown | Fires during each second of the warningLength parameter. | function(){} |
| onTimeout | A callback to fire when the session times out. | function(){} |
| onAbort | A callback to fire when the script is aborted due to too many failed polling requests. | function(){} |
Enjoy!
Related posts: