Managing Application State

One of the most difficult tasks that a Web developer faces is how to manage state-of-the-session information for an application. This problem surfaces when you want to track information from users who log onto your site. For example, if users go from page to page selecting items to buy, you need to be able to store that information somewhere so that you can display a list of all the items ordered and the total cost. You might store that information in a database, but you need a temporary storage method while users are accessing your Web page.

This is exactly what Active Server Pages lets you do with its Server, Application, and Session objects. These objects let you interact with ASP. You can use the objects to do certain tasks, such as send cookies to the client's browser or store information in the object for later reuse.

The Active Server Application

Just as a Web site is actually a collection of HTML files in a directory on your Web server, the Active Server application (also known as an ASA or ASP application) is actually a set of .asp and .htm files. Of course, you can use .htm files only, but if you want to use server-side scripting, you need to use at least some ASP files because the server won't even try to execute server-side script code in an .htm file.

One particular file in the ASP application is used to declare objects and define event procedures: the global.asa file.

The Application as a Unit

An ASP application is a collection of all the .asp, .htm, and other pages and documents that comprise the Web site. A Web site in the context of an application is defined as a virtual root that contains a global.asa file, including all the files and directories down to any subdirectory that contains a global.asa file. When a subdirectory contains a global.asa file, that subdirectory and all of its children are part of another application.

Think of an ASP application in the same way that you think of other familiar applications. For instance, a traditional Visual Basic application might consist of many different .dll and .exe files, among others. The files from one application can also be shared among applications. An ASP application works the same way. Files in one ASP application can be used by another ASP application.

You store global information within one application using the Application object as a global storage container. To share information between two or more applications, you must use a file or some other persistent storage mechanism, such as a database.

The global.asa File

The global.asa file is included automatically when you create a new Web project in Visual InterDev, unless you have disabled this feature. Instead of having the .asp extension that the rest of the ASP files have, it has an .asa extension. This file defines event procedures that are triggered by events when the application or session starts or ends. The application begins when the first user accesses the application, and it ends when the last user's session times out. (In IIS 3, the application does not end until the Web service is stopped.) Each user visit to your Web site counts as a session.

The Application_OnStart event occurs when the first user starts a session in your application. For example, the event occurs when someone visits your Web site for the first time. The user session is identified by the session ID created automatically in global.asa. If that person is still at your site (still has an active session) when another person visits, the Application_OnStart event does not occur. In other words, one instance of the application serves all sessions. You can write code (event procedures) that is triggered when the application starts and ends. The Application_OnEnd event does not occur when the last user leaves the application or the last user's session times out, but rather when the Web service stops.

The Session_OnStart event procedure is a good place for the application's startup code, which is similar to the OnLoad event of a Visual Basic application's main form. You can write event procedures that are triggered every time someone new comes to or leaves your site. This Session_OnStart event is often used to record the number of visits to a site. There can thus be many Session objects in existence simultaneously—one for each person using your site.

By default, as soon as a user hits the first ASP Web page of a Visual InterDev project, the global.asa page is executed. During this execution, the request from the browser is checked to see if there is a valid session cookie being sent. If so, global.asa is not executed, since the user is in an already-active session for that application, but the ASP Web page is executed.

If a valid session cookie is not coming from the browser for that application, a new session is started and the following actions are performed:

  • Global.asa is executed.
  • A unique session identifier (SessionID) is created for that user.
  • A cookie is created and sent to the browser so subsequent requests can be recognized as part of an existing session.
  • If this is the first session for an application, the Application_OnStart event occurs.
  • The Session_OnStart event occurs.

Session and Application Scope

Just as a normal procedural program has scope, so does the ASP application. But the ASP application has two types of variable scope, and two types of objects hold the variables for each scope.

Each ASP application has a single Application object, which is shared among all users who are running the application. Other ASP applications can refer to the Application object and will all refer to the same object.

The Session object has a smaller scope. Each person that visits your application gets his or her own session. The user's Session object is shared among all of the ASP Web pages in your site, but other people visiting your application have their own sessions.

If you have a variable named FavoriteTeam that you fill in from a form in your application, you can store it in one of several places. One way is to store it on the ASP Web page that handles the form by declaring it as a variable, as shown here:

Dim FavoriteTeam FavoriteTeam = "Oakland Raiders" 

In this case, the variable loses its value when the user leaves the page, so if you're not storing it (in a database or elsewhere), it disappears.

You can also store the variable in the Session object:

Session("FavoriteTeam") = "Oakland Raiders" 

This way, even as the user moves from page to page, the value remains. However, other people who log onto your Web site cannot see what the first user's favorite team is because each user has his or her own session.

You can also store the variable in the Application object:

Application("FavoriteTeam") = "Oakland Raiders" 

This FavoriteTeam variable has the same value on every page within the application. Other people also see this value when they visit your Web site. In fact, someone else can visit the site, load the form that sets the value of FavoriteTeam, and enter a new value. After everyone leaves the site, the application still keeps this value. The value persists until the Web service stops or is changed by another user.

You can turn off session-state management by checking the Sessionless ASP Pages property on the Editor Defaults page in the Project Properties dialog box. If you check this property, Visual InterDev inserts this line as the first line in each new ASP file you create:

<%@ Language=VBScript  EnableSessionState=False%> 

This line turns off session management in each page. You can selectively turn it back on by changing the line to true in each page:

<%@ Language=VBScript  EnableSessionState=True%> 

The Application Object

In an ASP application it is important to be able to store application-related information, such as the number of visits made to the application. If you plan to sell advertising space on your Web site, for example, you'll want to know how many hits the site gets because the value of the space will be directly related to the number of hits.

The Application object is a kind of storage area in which you can place variables and make them available not only to any script in your application but also across all instances of your application. If 100 people visit your Web site and you store a value in the Application object, all 100 "copies" of your site can reference the Application object and access that value.

The Application object is therefore a great place to store simple values that apply to the entire application, such as the number of hits your Web site gets. Unfortunately, it is not a good place to store large, complex values, such as the inventory of your warehouse.

An application variable is created when you assign it a value, as in this example:

Application("NumOfHits") = Application("NumOfHits") + 1 

The first time this line is executed, the NumOfHits application variable is created and stored in the Application object. Like all numeric variables in VBScript, it starts off with a value of 0. Every subsequent time the line is executed, the same value is updated, regardless of how many users are on the Web page simultaneously.

The ability to share this number between different running Web sessions raises an interesting question: What happens when two people are on your Web server at once and they both hit that statement at exactly the same time? A couple of methods of the Application object handle this scenario: Lock and Unlock. The Lock method puts a lock on the Application object so that no other instance of the application can perform any operation on it. Unlock reverses the process so that the other copies have access to the Application object again. You can modify your hit counter to take advantage of this:

Application.Lock Application("NumOfHits") = Application("NumOfHits") + 1 Application.Unlock 

When this code is executed, the application is temporarily locked, the NumOfHits variable of the Application object is modified, and the Application object is unlocked. In this way, no two copies can ever simultaneously modify the Application object. If a client tries to modify the Application object when it is locked, the client must wait until the copy holding the lock unlocks it or until the Web page times out.

You must keep the application locked for as little time as possible because other clients might be waiting. In the previous example, the application is locked only for as long as it takes to update the hit counter, and then it is released.

The NumOfHits variable in this example disappears when the application ends. If you want to use an application variable to count the number of Web site hits, you have to save its value when the application ends and retrieve its value when the application restarts.

Application events

In addition to running scripting code in a page that's being loaded, an ASP application can also respond to events. Unlike forms and controls in Visual Basic that have dozens of events, the Application object has only two events: Application_OnStart and Application_OnEnd. The Application object's events are caused by actions from outside the application. You can write code that you want to execute when these events occur.

The Application_OnStart event occurs the first time someone starts a new session of your Web application. For instance, let's say that no one is visiting your Web site. Then users A, B, and C visit your site, in that order. Your Application_OnStart event occurs only when user A hits the site. When users B and C arrive a fraction of a second later, the application is already running because of user A; therefore, Application_OnStart does not occur again.

On the flip side, you have the Application_OnEnd event, which occurs only when the IIS's Web service shuts down.

Application_OnStart

The Application_OnStart event code is placed in the global.asa file. The following is an example of a global.asa file that contains event procedures for the OnStart and OnEnd event procedures of both the Application and the Session objects:

<SCRIPT LANGUAGE="VBScript" RUNAT="Server"> Sub Session_OnStart     'Insert script to be executed when      'a session starts End Sub Sub Session_OnEnd     'Insert script to be executed when      'a session ends End Sub Sub Application_OnStart     'Insert script to be executed when      'the application starts End Sub Sub Application_OnEnd     'Insert script to be executed when      'the application ends End Sub </SCRIPT> 

The global.asa file created by the Web Project Wizard has comments that tell you how to create these event handlers. You can use the application's events to count the number of visitors to your Web site. The AdventureWorks sample application (available from Microsoft's web site at www.microsoft.com, and also as part of the ASP software) uses Application_OnStart to get information from a text file on the system and save it in the Application object. A portion of the sample's code is shown below.

<SCRIPT LANGUAGE="VBScript" RUNAT="Server"> SUB Application_OnStart     ' This script executes when the first user comes to the site.     ' Open file and read the number of visitors so far     VisitorCountFilename = Server.MapPath("/AdvWorks") + _         "\visitors.txt"     Set FileObject = _         Server.CreateObject("Scripting.FileSystemObject")     Set Out = _         FileObject.OpenTextFile _             (VisitorCountFilename, 1, FALSE, FALSE)     ' Initialize soft visitor counter here     Application("visitors") = Out.ReadLine     ' Store physical filename of file containing the     ' visitor count     Application("VisitorCountFilename") = VisitorCountFilename END SUB </SCRIPT> 

This script creates a reference to an object using the Set FileObject = Server.CreateObject("Scripting.FileSystemObject") syntax. The FileObject object is used to read and write the number of visitors to a text file. The script uses the FileSystemObject object named FileObject to open a text file. The Visitors variable in the Application object is then set to the value read from the text file. This technique retrieves the number of visitors. While the application is running, the value of Visitors is incremented when the session starts. (The script for the Application_OnEnd event for the same application is shown below.)

<SCRIPT LANGUAGE="VBScript" RUNAT="Server"> SUB Application_OnEnd     ' This script executes when the server shuts down or when      ' global.asa changes.     ' Overwrites the existing visitors.txt file     Set FileObject = _         Server.CreateObject("Scripting.FileSystemObject")     Set Out = FileObject.CreateTextFile _         (Application("VisitorCountFilename"), TRUE, FALSE)     Out.WriteLine(Application("visitors")) END SUB </SCRIPT> 

The Application_OnEnd event procedure again creates a FileSystemObject object named FileObject that is used to create a text file named visitors.txt. This file overwrites the file you read in OnStart and writes the new number of visitors to the file. Writing the number of users to the file is one way to save the number of visits to this site between application sessions.

The Session Object

The Session object is similar to the Application object in that it also provides scope for variables. The variables are available to all pages in your application, but the Session object has a more limited scope. The same object is not available to all users of the site (for example, the Application object); instead, each user has his or her own Session object. Any variables stored in the Session object are for that session only.

Session variables are analogous to global variables in a traditional program. They are available throughout the program, but if you start another copy of the program, that other copy has its own global variables.

The Session object also has Session_OnStart and Session_OnEnd events, similar to those of the Application object. In the previous examples, the application read the number of visitors from a text file when it started and saved this number to the text file when it ended. The application needs to increment that number each time someone enters the site. The Session_OnStart event procedure is the perfect place for that code, as shown below.

<SCRIPT LANGUAGE="VBScript" RUNAT="Server"> SUB Session_OnStart ...     ' Increase the visitor counter     Application.Lock     Application("visitors")= Application("visitors") + 1     t_visitors = Application("visitors")     Application.UnLock     Session("VisitorID") = t_visitors     ' Periodically, save to file     If t_visitors MOD 15 = 0 Then         Set FileObject = Server.CreateObject( _             "Scripting.FileSystemObject")         Set Out= FileObject.CreateTextFile _             (Application("VisitorCountFilename"), TRUE, FALSE)         Application.Lock         Out.WriteLine(t_visitors)         Application.UnLock     End If ... END SUB </SCRIPT> 

You'll also notice that the visitor count is periodically saved to disk. This is because the Application_OnEnd event only fires when the Web service stops gracefully. Saving the visitor count every 15 visitors or so within the Session_OnStart event procedure keeps the visitor count more accurate even if the Web service stops abnormally.

The OnStart and OnEnd events for the Session object are located in the global.asa file along with the Application object's events. With this code in place, the Visitors application variable is incremented anytime someone visits the site. Remember to lock the application before you change the value to make sure only one client can execute that statement at a time.

The Session object also has two properties: SessionID and Timeout. SessionID has a data type of LONG. It uniquely identifies the session on the server. Don't use this value as the primary key of a database because the same SessionID might be used again after the server is shut down and restarted.

Timeout specifies the number of minutes the session stays active if the user does not refresh or request a page from your application. At the end of the period defined by Timeout, the session is destroyed and all its resources are returned to the server. By default, session Timeout is 20 minutes. This default is set in the registry, under the SessionTimeout entry.

You can also force a session to be destroyed by calling its Abandon method. This ends the session at the end of the current VBScript. Further references to the Session object will create a new session.

Sessions and cookies

You might wonder how ASP knows that a browser requesting a page is already a member of a session. After all, when a browser requests a page, it is simply asking that a file be downloaded. How can the server know that this is the same person who has been browsing around your system for the last hour and a half? The answer is in the cookie.

When the user first accesses a page in your application, the server scans the request's HTTP header for a SessionID. If the user is hitting your site for the first time, there is no SessionID, so the server generates an ID and asks the browser to create a cookie with this ID. Of course, this cookie will not last forever. The server specifies that this cookie should disappear in a certain amount of time. The next time the user asks for a page, the server will be able to find the cookie with the SessionID and know what session the user is associated with, and therefore what session variables the ASP Web page should use.

You can also set the Timeout value for a session. The Timeout value is how long the session lasts before it is terminated. This is done with the Timeout property of the Session object. The server takes the Timeout property of the Session object and sets the SessionID cookie to expire in that much time. Every time the user requests a page from your server, the server resets the cookie's expiration timer.



Programming Microsoft Visual InterDev 6. 0
Programming Microsoft Visual InterDev 6.0
ISBN: 1572318147
EAN: 2147483647
Year: 2005
Pages: 143

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net