Active User Count Without Global.asaby Josh Painter( Webmaster of Toastforums.com) Introduction Introduction
So you've got your killer website up and running, and you're wanting to add a few little "perks." One of the hottest trends today is to show an "Active User Count" that shows exactly how many people are currently connected to your website. Many articles have already been written showing exactly how to do this using the global.asa file, so I won't even bother to explain that method. ASP 101 has a great article explaining the global.asa method of counting active users.What I'd like to do is show you how to not use the global.asa file. I'm not saying using the global.asa file is bad--far from it. If you can use it then please do; it will probably yield a bit better performance. But there are many reasons why you might not want (or simply can't) use a global.asa file. Perhaps your host does not allow a global.asa. Maybe your site is hosted in a subdirectory of an existing site, and they won't set up an IIS application for you, so a global.asa file will do you no good. Or you might even not want to mess with an existing global.asa file, or not have access to do so. Personally, I needed to have this functionality for a web application I've been building (shameless link) and one of my design goals was that the Active User Count would NOT require use of a global.asa. I didn't want to bother with helping webmasters try to merge my code in with an existing global.asa, or guide them through setting up an existing IIS application so they could use my global.asa. Many of them couldn't even if they know how, because their web host doesn't allow it. So, this is the solution. Quick Explanation
To make a manual Active User Count, we have a few options about where to store the active users on the server. We could store them in a database, in a text file, or in server memory in an Application variable. I chose to go with Application variables. Databases may be fast, but I don't like to query a database on *every* hit to a page unless absolutely necessary. Text files could get cumbersome, and I don't want to worry about file permissions. So the logical choice is Application variables. Application variables are very fast to access, since they reside in the web server's memory, and are available on just about every ASP web host out there. I make use of three Application variables: one that holds the number of online users, another that holds a list of unique users and the last time of their activity, and the final variable remembers when the last cleanup occurred. We'll use the SessionID for a unique key of each user, and the simple Now() function to tag each SessionID with the time of last activity. So, without any more explaining, here is the "LogActiveUser" function: LogActiveUser Routine Sub LogActiveUser Dim strActiveUserList Dim intUserStart, intUserEnd Dim strUser Dim strDate
strActiveUserList = Application("ActiveUserList")
If Instr(1, strActiveUserList, Session.SessionID) > 0 Then Application.Lock intUserStart = Instr(1, strActiveUserList, Session.SessionID) intUserEnd = Instr(intUserStart, strActiveUserList, "|") strUser = Mid(strActiveUserList, intUserStart, intUserEnd - intUserStart) strActiveUserList = Replace(strActiveUserList, strUser, Session.SessionID & ":" & Now()) Application("ActiveUserList") = strActiveUserList Application.UnLock Else Application.Lock Application("ActiveUsers") = CInt(Application("ActiveUsers")) + 1 Application("ActiveUserList") = Application("ActiveUserList") & Session.SessionID & ":" & Now() & "|" Application.UnLock End If End Sub
|
So let's take this line by line. First, we are copying the Active User list into a local variable. We are going to be doing lots of string manipulation, and we don't want to make a call out to the Application Variables collection every time we need to inspect the Active User list. Then we need to check to see if this user is already in the list. We do this by the simple Instr call to see if his SessionID exists. If it doesn't, its easy--we just add one to the ActiveUsers parameter and add this new SessionID and current time to the Active User list. If the SessionID already exists, we've got a bit more work to do. We've got to find this user in the list and update his time stamp. The ActiveUserList variable will look something like this at any one time:
| 716763555:1/4/2001 11:10:23 PM|616733525:1/4/2001 11:11:45 PM|8616433235:1/4/2001 11:15:58 PM | So we need to extract the user that we're looking for, change his timestamp to Now(), and insert him back in the list. Pretty easy to do. First we find the beginning of the user by searching for SessionID. Since the users are delimited by a pipe "|" symbol, we just search for the pipe starting with the beginning of the SessionID to find the end of the User's timestamp. Now that we have the beginning and the end, we can just replace this entire "chunk" of the string with the SessionID and current timestamp. This will effectively "reset" the user's timestamp. But, how do we clean up ActiveUsers as their timestamps get old? Let's look at the ActiveUserCleanup routine. ActiveUserCleanup Routine
Sub ActiveUserCleanup Dim ix Dim intUsers Dim strActiveUserList Dim aActiveUsers Dim intActiveUserCleanupTime Dim intActiveUserTimeout
intActiveUserCleanupTime = 1 'In minutes, how often should the ActiveUserList be cleaned up. intActiveUserTimeout = 20 'In minutes, how long before a User is considered Inactive and is deleted from ActiveUserList
If Application("ActiveUserList") = "" Then Exit Sub
If DateDiff("n", Application("ActiveUsersLastCleanup"), Now()) > intActiveUserCleanupTime Then
Application.Lock Application("ActiveUsersLastCleanup") = Now() Application.Unlock
intUsers = 0 strActiveUserList = Application("ActiveUserList") strActiveUserList = Left(strActiveUserList, Len(strActiveUserList) - 1)
aActiveUsers = Split(strActiveUserList, "|")
For ix = 0 To UBound(aActiveUsers) If DateDiff("n", Mid(aActiveUsers(ix), Instr(1, aActiveUsers(ix), ":") + 1, Len(aActiveUsers(ix))), Now()) > intActiveUserTimeout Then aActiveUsers(ix) = "XXXX" Else intUsers = intUsers + 1 End If Next
strActiveUserList = Join(aActiveUsers, "|") & "|" strActiveUserList = Replace(strActiveUserList, "XXXX|", "")
Application.Lock Application("ActiveUserList") = strActiveUserList Application("ActiveUsers") = intUsers Application.UnLock
End If
End Sub |
Let's look at this routine line by line. The first thing we do is set some internal variables that decide when to cleanup, and how long before a User is considered Inactive. The variables intActiveUserCleanupTime and intActiveUserTimeout control these times, respectively. If the ActiveUserList is blank, we have nothing to do here, so Exit Sub. If the difference (in minutes) between the time we last ran the cleanup procedure and the time right now is greater than intActiveUserCleanupTime, let's run cleanup (this is better for performance--we only want to run cleanup every minute or so, not every time the calling script is hit). Immediately set the ActiveUsersLastCleanup variable to Now, so if another script calls this procedure while we are doing our work it will think that it is not yet time to run cleanup. Now we will copy the ActiveUserList to a local variable for increased performance and convert it to an array so we can loop through all the users. We loop through each user, and if we find a timestamp that is older than the intActiveUserTimeout variable, we will replace the entire User with "XXXX", and delete him later (we must do this because VBScript does not natively support any advanced array handling like deleting or inserting elements). Now that we've marked inactive users, we'll convert the Array back to a string. We end the string with our delimiter "|" to make the next step easier. Replace any occurences of "XXXX|" that we find to "", effectively deleting the user from the ActiveUserList. Now its time to store the variables back into the Application variables. Getting it up and running with your Site This should be relatively easy. Just put these functions in a file and include it with any pages that will need to log Active Users and show an Activer User Count. So your script might look something like this:
<%
Call LogActiveUser() Call ActiveUserCleanup()
Response.Write "There are " & Application("ActiveUsers") & " active users currently online."
%>
|
Shameless Plug If you would like to see this code in action, head over to toastforums.com. See the "Current Online Forum Users" up in the right corner? That is using this exact code! Oh, and if you need a free ASP message board for your website, try Toast! Happy coding! Josh Painter | DISCLAIMER: The content provided in this article is not warranted or guaranteed by Developer Shed, Inc. The content provided is intended for entertainment and/or educational purposes in order to introduce to the reader key ideas, concepts, and/or product reviews. As such it is incumbent upon the reader to employ real-world tactics for security and implementation of best practices. We are not liable for any negative consequences that may result from implementing any information covered in our articles or tutorials. If this is a hardware review, it is not recommended to open and/or modify your hardware. |
More ASP Code Articles More By aspfree developerWorks - FREE Tools! | This whitepaper presents the benefits of successfully introducing static analysis into your organization using IBM Rational Software Analyzer. Additionally, it identifies some common pitfalls that can hinder the effective use of static analysis tooling as well as presents 10 simple strategies designed to help you quickly realize the value of static analysis using Rational Software Analyzer. FREE! Go There Now!
| | | | Visit IBM developerWorks to download a free trial version of WebSphere Business Modeler Advanced V6.1.1, IBM’s premier business process modeling and analysis tool for business users that offers process modeling, simulation, and analysis capabilities. IBM WebSphere Business Modeler helps you visualize, understand, and document business processes for continuous improvement. FREE! Go There Now!
| | | | Download a free trial version of IBM DB2 9.5 for Linux, UNIX, and Windows. DB2 9 is the result of a five-year development project that transformed traditional (static) database technology into an interactive data server that merges the high performance and ease of use of DB2 with the self-describing benefits of XML. FREE! Go There Now!
| | | | Download a free trial version of IBM Rational Developer for System z, software that can help you deliver core development capabilities; the power of Java Platform, Enterprise Edition (Java EE); and rapid application development support to diverse enterprise application development teams. With comprehensive development tools to help create, deploy and maintain traditional enterprise and composite applications, Rational Developer for System z enables developers with different technical backgrounds to easily participate in important technology projects. FREE! Go There Now!
| | | | Join this webcast to see how IBM Data Studio Developer and pureQuery can take the pain out of Java data access. uApplications developed using both Java and SQL have become a common requirement. Database connectivity using Java Database Connectivity (JDBC) to create an application is a multi-step tedious process, and tooling that covers both SQL and Java has been unavailable, until now. IBM Data Studio introduces the pureQuery platform: a high-performance, Java data access platform focused on simplifying the tasks of developing, managing, and optimizing database applications and services. FREE! Go There Now!
| | | | Rational Build Forge Express Edition is an automation framework that packages the latest enterprise-grade technologies into a reliable, flexible and robust configuration designed and priced specifically for small to midsize businesses. The new Rational Build Forge Express eKit provides you with valuable resources – including a case study, podcast, demo, and articles – to help you increase staff productivity, compress development cycles and deliver better software, fast. FREE! Go There Now!
| | | | Join this Rational Talks to You teleconference on December 4 at 1:00 pm ET to discuss how Rational Method Composer can help meet your compliance objectives. Get your questions answered! FREE! Go There Now!
| | | | Get a free trial download of the latest version of IBM Rational Tester for SOA Quality V7.0.1, a functional and regression testing tool that enables the creation, comprehension, modification and execution of testing GUI-less Web services. FREE! Go There Now!
| | | | Visit IBM developerWorks to try the IBM SOA Sandbox for process. The SOA Sandbox for process focuses on providing a trial environment with the necessary tooling and components required to gain a better understanding of business processes and how to best improve existing business processes to derive value quickly. FREE! Go There Now!
| | | | Attend this launch webcast with Scott Hebner, Vice President of IBM Rational Marketing and Strategy, where he will overview Rational’s new offerings and programs to help customers accelerate software innovation on System z. He will discuss how these solutions help organizations extend their core business processes toward modern architectures such as SOA and web technologies to deliver business improvements that stand the test of time. FREE! Go There Now!
| | | | All FREE IBM® developerWorks Tools! | |