Overview
This object provides a drop-in component to replace the ASP Session object for use on a web farm, where the session state is stored in a database. The component needs to be placed in COM+, as it uses IObjectContext to get hold of the ASP request/response objects to manage the session state cookies.
The component should be instantiated on every page, whether used or not, to prevent sessions from timing out. This is most easily achieved by using a common page header. Data is not writen back to the database (other than the last used time) if the session state is not modified, so there is little cost to doing this.
The component uses a single cookie, filled with 128-bits of cryptographic grade random data. It is therefore hard to steal other peoples sessions (especially when combined with the use of a timeout.
Two databases are supported out of the box: SQL server (untested for this release — let me know if it’s broken and I’ll fix it), and Oracle. Other databases should simply be a case of modifying the code to support the required differences in SQL. In this case, most incompatibilities are caused by differences in date handling. In order to support accurate timeouts across multiple servers, the clock on the database server is used for all such calculations.
Build or Download
You can get the source from subversion (see the main page for details). Alternative, pre-built binaries are packaged with the gnomon installer, available here.
Configure the components, database and registry
To configure the components, do the following:
- Register the NPSLDictionary component (regsvr32 NPSLDictionary.dll).
- Create an empty library package using Component Services Manager and drop NPSLSession3.dll in to register it with COM+
Note that the step above is not necessary if you have created a COM+ package with the gnomon installer.
To configure the database, choose the appropriate script. Pick a schema/catalogue, and run the script to create the SessionState table. This stores information on the session including the contents of the NPSLDictionary object, the last used time of the session, and the session’s timeout value.
Note that old sessions are not automatically removed and you will probably want to configure a job on your database to remove these.
The component requires a single registry key containing a connection string for the database. In the binary, this is stored at HKLM\SOFTWARE\NPSL\npslda2\security\ConnectionString (the name is for historical company reasons). There is a registry script with the distribution which will create a sample key, but you obviously need to modify this to suit your database.
Use the component
As previously mentioned, the simplest way to use the component is to have a common include script that instantiates it at the top of every page (at least, every page that requires sessions). You should also set the timeout value here (it only needs to be done on session creation as it is persisted to the database, but there is little weight in setting it — typically it is more expensive to decide if this is necessary). An example of an include script is:
' Create the session object
Dim SessionX
Set SessionX = _
Server.CreateObject("NPSLSession3.SessionX")
SessionX.Timeout = 60 * 60 ' 1 hour
To use the code in your page:
SessionX("foo") = "bar"
That’s it. Note that due to the nature of object destruction it is not possible to report errors in persisting to the database at the end of a page (an extension would be to get the component to write this information to the event log; not hard, I just don’t have trouble with this). If you want to trap errors writing to the database during setup, then you can use the SaveChanges method, e.g.
SessionX("poo") = "sticky"
SessionX.SaveChanges
The other methods are SessionID (which returns the current session ID, or you can set it specifically if you have a special reason for doing this) and Abandon. Abandon sets the cookie to expire at some point in the past (the only known method of clearing a cookie) so that the session information is lost. Note that Abandon does not delete data; this is felt best left to a batch job to avoid the unnecessary load on the database server at the time. If you have a client that just won’t let go of a cookie (I haven’t seen one to date), then you may need to set the LAST_USED time in the database to something very long ago to prevent this from occurring (or delete the state).
Note that no expiry date is set on the cookie by default; this is to avoid problems with sending cookies to clients with bad clocks (and there are a lot of those, believe me). The best way to combat this is to use a single, central clock.
Bugs
Bugs are tracked through bugzilla. Please report any bugs here, preferably with an attached test case indicating the problem, or even better, a patch (diff -U prefered).
If you are unsure if something is a bug, then email me.