Weird Thoughts From Eric's Head

Categories : All | AJAX | BUSINESS | PERSONAL | PROGRAMMING | BOOK REVIEW

Update User's Session with AJAX
[edit]Make sure to look at the new version of the script here: Round 2 version[/edit]
Well I am a little behind on my blogging here! Well I said I was going to do another AJAX example so here we go.

On some applications I help to develop, users were complaining that they were getting timed out of the application. I have no idea what they were doing on a single page for 30 minutes, but they complained. I guess they should not take that phone call!

Anyway we needed a solution to notify the user they were about to be timed out without posting back the page. Well since I am writing Ajax in Action, I proposed an Ajax solution. The Ajax solution keeps us from posting back the page to the server or opening up a pop up windw. Both methods have there flaws since the post back method can loose data if we happended to mis a viewstate field and the pop up window may be blocked by a pop up blocker. You can never be sure that the pop up would get through.

So I came up with a little script that uses AJAX to call a server side page. The server side, when called, updates our session. So the code for the server is only a few lines.

Select your language so you see the right code!



VB.NET code
Now with a .net page, we need to remove all but the code behind reference from our aspx page. In this case I called the page sessionUpdater.aspx.

<%@ Page Language="vb" AutoEventWireup="false" 
Codebehind="sessionUpdater.aspx.vb" Inherits="TestAJAX.sessionUpdater"%>
The code behind then just sets the content type of the page and then outputs a string with the time stamp within the Page_Load.
Private Sub Page_Load(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles MyBase.Load
    Response.ContentType = "text/xml"
    Response.Write("Session Updated - Server Time: " & DateTime.Now.ToString)
End Sub
Then we have the Client Side code. To make this easy we can use an external JavaScript file so we need to link to it in our page.
<%@ Page Language="vb" AutoEventWireup="false" Codebehind="sessionTimeout.aspx.vb" Inherits="TestAJAX.sessionTimeout"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
  <head>
    <title>sessionTimeout</title>
    <script type="text/javascript" src="SessionWarningTimer.js"></script>
  </head>
  <body>
    <form id="Form1" method="post" runat="server">
    <</form>
  </body>
</html>
Then we have our external JavaScript file (SessionWarningTimer.js):
var reqXML;
    
function LoadXMLDoc(url){ 
  if (window.XMLHttpRequest){ //Mozilla, Firefox, Opera 8.01, Safari
    reqXML = new XMLHttpRequest(); 
    reqXML.onreadystatechange = BuildXMLResults; 
    reqXML.open("GET", url, true); 
    reqXML.send(null); 
  }
  else if(window.ActiveXObject){ //IE
    reqXML = new ActiveXObject("Microsoft.XMLHTTP"); 
    if (reqXML) { 
      reqXML.onreadystatechange = BuildXMLResults; 
      reqXML.open("GET", url, true); 
      reqXML.send(); 
    } 
  }
  else{ //Older Browsers
    alert("Your Browser does not support Ajax!");
  }
} 

function BuildXMLResults(){
  if(reqXML.readyState == 4){ //completed state
    if(reqXML.status == 200){ //We got a sucess page back
         
      //Check to verify the message from the server 
      if(reqXML.responseText.indexOf("Session Updated - Server Time:") == 0){
        window.status = reqXML.responseText; //display the message in the status bar
        SetTimer(); //restart timer
      }
      else{
        //display that that session expired
        alert("Your session appears to have expired. You may loose your current data.");
      }
    } 
    else{
      //display server code not be accessed
      alert("There was a problem retrieving the XML data:\n" + reqXML.statusText);
    }		
  }
}
      
function ConfirmUpdate(){
  //Ask them to extend
  if(confirm("Your session is about to expire. Press 'OK' to renew your session.")){
    //load server side page if ok
    LoadXMLDoc('sessionUpdater.aspx'); 
  }
}      
      
var timerObj;
function SetTimer(){
  //How long before timeout (should be a few minutes before your server's timeout
  var dblMinutes = .2;
  //set timer to call function to confirm update 
  timerObj = setTimeout("ConfirmUpdate()",1000*60*dblMinutes);
}
      
//start the timer
SetTimer();
JSP code
We need to set the content type and return a string with a timestamp back to the client.
<%@ page contentType="text/xml"%>
Session Updated - Server Time: <%= new java.util.Date() %>
Then we have the Client Side code. To make this easy we can use an external JavaScript file so we need to link to it in our page.
<html>
  <head>
    <title>sessionTimeout</title>
    <script type="text/javascript" src="SessionWarningTimer.js"></script>
  </head>
  <body>
    <form id="Form1" method="post">
    </form>
  </body>
</html>
Then we have our external JavaScript file (SessionWarningTimer.js):
var reqXML;
    
function LoadXMLDoc(url){ 
  if (window.XMLHttpRequest){ //Mozilla, Firefox, Opera 8.01, Safari
    reqXML = new XMLHttpRequest(); 
    reqXML.onreadystatechange = BuildXMLResults; 
    reqXML.open("GET", url, true); 
    reqXML.send(null); 
  }
  else if(window.ActiveXObject){ //IE
    reqXML = new ActiveXObject("Microsoft.XMLHTTP"); 
    if (reqXML) { 
      reqXML.onreadystatechange = BuildXMLResults; 
      reqXML.open("GET", url, true); 
      reqXML.send(); 
    } 
  }
  else{ //Older Browsers
    alert("Your Browser does not support Ajax!");
  }
} 

function BuildXMLResults(){
  if(reqXML.readyState == 4){ //completed state
    if(reqXML.status == 200){ //We got a sucess page back
         
      //Check to verify the message from the server 
      if(reqXML.responseText.indexOf("Session Updated - Server Time:") == 0){
        window.status = reqXML.responseText; //display the message in the status bar
        SetTimer(); //restart timer
      }
      else{
        //display that that session expired
        alert("Your session appears to have expired. You may loose your current data.");
      }
    } 
    else{
      //display server code not be accessed
      alert("There was a problem retrieving the XML data:\n" + reqXML.statusText);
    }		
  }
}
      
function ConfirmUpdate(){
  //Ask them to extend
  if(confirm("Your session is about to expire. Press 'OK' to renew your session.")){
    //load server side page if ok
    LoadXMLDoc('sessionUpdater.jsp'); 
  }
}      
      
var timerObj;
function SetTimer(){
  //How long before timeout (should be a few minutes before your server's timeout
  var dblMinutes = .2;
  //set timer to call function to confirm update 
  timerObj = setTimeout("ConfirmUpdate()",1000*60*dblMinutes);
}
      
//start the timer
SetTimer();
Save it, then we can test this out.

Open up the page and wait until you get the warning.
confirm image

Then click the ok button
timestamp image

You can see that in the status bar, we have the time form our server showing we got the data from the server. Hopefully this shows you how easy it was to send a response to the server, retrieve its value, and display it on the screen.

Eric Pascarello
Moderator of HTML/JavaScript at www.JavaRanch.com
Author of: JavaScript: Your Visual Blueprint for Dynamic Web Pages
Co-Author of: Ajax in Action