HTTP is a stateless protocol. When a client sends a request to the server, the server doesn’t know if it's the client’s first or 42nd request. This poses a problem for Active Server Pages (ASP), where it is often necessary to associate server-side variables with a particular client. That association is one of the ways that Web sites are able to send me the Jethro Tull CD that I ordered instead of the Barry Manilow CD that someone else ordered at the same time. ASP handles this association through the use of a unique client identifier called a session ID, which is assigned to each client at the beginning of his or her browser session.
Let's look at some of the issues surrounding the use of session IDs in both "classic" ASP and ASP.NET. Then, we'll consider what happens with sessions when multiple Web servers come into play.
What is the session ID?
The session ID is a read-only value that uniquely identifies the current clients to the Web server. In classic ASP, session IDs are assigned in a sequential manner—the session ID 706616433 is followed by the session ID 706616434, and so on. The classic ASP session ID is stored on the client’s machine in the form of an encrypted nonpersistent cookie. For example, the session ID 706616434 would be stored on the client machine as the cookie ASPSESSIONIDGQQGQGCS=JHMBOBKCBINEHLPKJHOPABBE.
ASP.NET has made a few changes to the session ID. When using ASP.NET, the session ID is a 120-bit string consisting of URL-legal ASCII characters. According to Microsoft’s documentation, session ID values are generated using an algorithm that guarantees their uniqueness, which prevents sessions from colliding when two clients attempt to use the same ID. In addition, the randomness makes it considerably more difficult to determine the ID of an existing session, providing additional security. As with classic ASP, the session ID in ASP.NET is usually stored as a nonpersistent cookie on the client. The format of this cookie varies only slightly from its classic ASP counterpart, for example, asp.net_sessionid=jhmbobkcbinehlpkjhopabbe.
In addition to the traditional nonpersistent cookie method of maintaining state, ASP.NET supports a “cookieless” mode. When the cookieless mode is enabled, ASP.NET embeds the session ID in the URL that is sent back to the client. This provides persistence for clients using browsers that either do not support cookies or have cookies disabled. Cookieless mode is worth keeping in mind, considering the current emotions concerning cookies and tracking customers with them.
How is the session ID used?
Each time a client makes a request, the cookie containing the encrypted session ID, if it exists, is sent to the server. The server then determines the session ID associated with the cookie and restores all session variables associated with the client. If the cookie does not exist, a new session ID is created and the encrypted session ID cookie is sent to the client machine. This enables ASP to keep track of individual clients on a Web site. It also allows ASP to associate server-side session variables with an individual session. The session variables are divided into two types:
- The Contents Collection
- The StaticObjects Collection
With both classic ASP and ASP.NET, Contents Collection session variables are associated with a particular client based upon the session ID. These variables are an associative array, like Visual Basic’s Collection object. Session variables work in exactly the same manner; the only real difference is that they are associated with a particular session. As with the Collection object, members of any type can be stored and retrieved using the unique key.
The StaticObjects Collection contains all of the objects with session-level scope that were added to the application using the <OBJECT> tag in the GLOBAL.ASA. Like the Contents Collection, the StaticObjects Collection is an associative array, and it's accessed in the same manner. Remember that the StaticObjects Collection contains only objects that were instantiated using the <OBJECT> tag and not those instantiated using Server.CreateObject.
Only one to a customer?
With a single Web server, maintaining state is, for all intents and purposes, automatic. The client gets its one and only unique session ID, and as long as a client is active at the site, the session information is maintained. Maintaining state becomes more complex when there is more than one Web server or if individual applications are located in a virtual directory that resides under the virtual directory of another application.
Each server operates independently of the others when assigning session IDs. Because of this, Web server A isn’t aware that Web server B just assigned session ID 706616434 to a client. So if Web server A gets a request from the client with session ID 706616434, it will be treated as a timed-out session and Web server A will assign a new session ID. When this happens, the client has lost state on Web server B and must start over from the beginning with no guarantee that it won’t happen again. One way to avoid this runaround is to ensure that all of the client’s requests are routed to the same server.
Having applications in virtual directories is a way to isolate the individual applications running on the same Web server. But it's important to remember that when an application calls another, a new session ID will be created. This causes the first session ID to be lost, along with any associated stored session variables. Depending upon the applications, the loss of state may not be a problem, but it’s important to keep in mind to avoid those late night/early morning debugging sessions.
ASP conquers the greatest challenge of creating persistent Web applications—maintaining state. This allows developers to create applications without having to create their own proprietary method of handling this. With ASP, some planning, and hard work, it is possible to create robust persistent applications.