Friday, July 06, 2007

Using Session variables to maintain state

Part 1
This article follows on from my earlier article about Application variables, and how they allow you to store "global" data for use by all your pages.
Session variables are very similar. You can create them and store data in them in exactly the same way:
// create a new Session variable to store the users name
Session ( 'Name' ) = 'James';

// display the name in any page on your site
Out ( 'Your name is ' + Session ( 'Name' ) );
The crucial difference between Application and Session variables is that Session variables are specific to each visitor to your site.

Background: The stateless web

The problem that Session variables have to overcome is that the HTTP protocol that you use to browse the web is stateless. Each request for a page is completely independant of earlier requests, so if you want subsequent pages to "remember" the users name that he entered on your front page you have to store that information somewhere.
This remembering of user-specific data is called "maintaining state". We'll see next how the ASP Session object can help us do just that.
Part 2

Creating a new session

The first time a new user visits a page on your site a new session is automatically created. How? Well, in answering that we'll discover the major limitation of the Session object - it relies on cookies.
If you don't know already, cookies are simply data stored on your computer and automatically sent to the server by browsers when requesting a page. (Incidentally, they are perfectly safe. They can't collect personal information from your computer like some think. Read more about privacy and cookies.)
So the first time a user visits, there's no cookie and the server creates a new session and sets a cookie with a unique value. As the user browses your site the cookie is sent back and forth between your computer and the server, allowing the server to recognise the user.
To your ASP page it's a transparent process. In case you're interested, here's the actual cookie we're sending back and forth right now:
Unless you have cookies disabled, or are using a browser that doesn't support them, you should see something like ASPSESSIONID followed by a lot of gibberish. That's the unique value I was telling you about, and how the server recognises you as an earlier visitor.

Disabling sessions

If you don't want to track sessions (and if you're not storing any data in the Session object, you don't) disable them. Your server will appreciate it since it won't have the overhead of managing all those cookies. Add this line to the top of your pages:
<%@ EnableSessionState=False %>
Part 3

Tracking new sessions

The server is nice enough to tell us when a new session is created by calling a function in your global.asa file, Session_OnStart( ).
If you don't have a global.asa, just create one - there's nothing magical about the file. A simple example is shown below:
<script language=JavaScript runat=server>

function Session_OnStart ( )
   // you must lock the global Application object
   // when writing to it - ok to read without lock
   Application.Lock ( );

   // one more active user
   Application ( 'ActiveUsers' )++;

   Application.Unlock ( );

In this example, as on my site, I use the Session_OnStart( ) function to increment a count of how many users are currently on my site, or more accurately how many active sessions there are (you'll see in a minute that there are always more active sessions than users on your site...).
There are no restrictions on what you can do in this function - you could initialize some Session variables in here, connect to your database, send emails - whatever.
Part 4

Ending a session

I've shown how a new session starts, but how does it end? There are two ways:
1. The user doesn't request or refresh a page within a specific time period.
2. Session.Abandon( ) is called from your ASP page.

Sessions timing out

By default, if a user doesn't make any requests from the server for 20 minutes that session is ended. Similar to before, the Session_OnEnd( ) function in global.asa is called at that point. Note that you can only use the Application, Session and Server objects in that function.
Setting timeout for the entire application
You can change the timeout value for all your pages by configuring IIS. On earlier versions of IIS on Windows NT you changed this setting in the Internet Service Manager, but that was renamed to the "Internet Information Services snap-in" in Windows 2000.
To find the IIS snap-in go to Control Panel / Administrative Tools / Internet Services Manager and then view the properties for the Default Web Site. On that dialog go to the Home Directory tab, and choose the Configuration button (nearly there!). Choose the App Options tab, and <phew> there's the setting!
Set it to as small a number as possible to increase the efficiency of your server. Set it larger than the time you expect users to read your largest page, or they could lose their session!
Setting timeout for a single session
You can also override the timeout for a single session by adding the following line into your code (although I can't think why you'd want to do this):
// this session will timeout after 5 minutes inactivity
Session.Timeout = 5;

Abandoning a session

You can end a session (almost) immediately by calling Session.Abandon( ). The rest of the page is still executed, and the Session object is still available for that page, but the session is ended when the page finishes executing. If you want the page to stop processing immediately too, call Response.End( ).
Remember that even though the session has ended, if the user requests a new page from your site a new session will automatically start.

Shape Yahoo! in your own image. Join our Network Research Panel today!