Keeping track of anonymous visitors versus logged-in users

In this recipe, we are going to take a look at a common task for most sites. We want to be able to keep track of how many users are present on our site at any given time. We will also attempt to distinguish between known (logged-in users) and unknown (anonymous) users. To keep track of users as they come to our site, we will need to attach some of the events, such as Session_Start and Session_End, which our application exposes. To distinguish between the known and unknown users, we will have to tap into our membership functionalities, such as registration, logging on, and logging off.

How to do it...

  1. Start by creating a new default ASP.NET MVC 2 application.
  2. Next, we will need to create a class to help us keep track of our users. We will call this class SiteVisitors and place it in the Models directory. The SiteVisitors class will provide us with the ability to keep track of how many visitors of each type are on our site at a given time. As we only ever want one instance of this class to exist at any one time during the lifetime of our application, we will use the singleton pattern to control the number of instances that are created. In its most simple form, the singleton pattern requires us to have a private constructor (so that no one can instantiate an instance of the class directly) and a static method, which will return an instance of the class to us. In this static method, we will check if we have created an instance or not and behave accordingly.

    Models/SiteVisitors.cs:

    public class SiteVisitors {
    private static SiteVisitors instance = new SiteVisitors();
    private SiteVisitors() { }
    public int UnknownVisitorCount { get; private set; }
    public int KnownVisitorCount { get; private set; }
    public static SiteVisitors Instance {
    get {
    return instance;
    }
    }
    }
    
  3. Now we need to create an Enum that will provide a method for us to identify the two different types of users—known and unknown. We will do this by creating a new Enum in the Models folder called VisitorTypes.cs.

    Models/VisitorTypes.cs:

    public enum VisitorTypes {
    UnknownVisitor = 0,
    KnownVisitor = 1
    }
    
  4. Once we have a manner in which to identify between the two types of users, we need to have the ability to assign the type to each visitor. We will do this by setting a value into each user's session called VisitorType. Rather than working directly with the session all over our application, we will create a wrapper class to handle this functionality for us. Therefore, we need to create a new class called SessionWrapper.cs in the Models folder. This class will have two methods—one method each to set the two different types into a user's session depending on who we think they are at the time, and another method to get the user's current type.
    public static class SessionWrapper {
    private const string c_visitorType = "VisitorType";
    public static void SetUnknownType() {
    HttpContext.Current.Session.Add(c_visitorType, VisitorTypes.UnknownVisitor);
    }
    public static void SetKnownType() {
    HttpContext.Current.Session.Add(c_visitorType, VisitorTypes.KnownVisitor);
    }
    public static new VisitorTypes GetType() {
    VisitorTypes result = VisitorTypes.UnknownVisitor;
    if (HttpContext.Current.Session[c_visitorType] != null)
    result = (VisitorTypes)HttpContext.Current.Session [c_visitorType];
    return result;
    }
    }
    
  5. With this groundwork set in place, we can now return to our SiteVisitors class to provide a bit more functionality. Currently, we are able to get an instance of the SiteVisitors class on which we have two properties from which we can read values. We now need to expose some helper methods that allow our application to toggle certain actions as an unknown user becomes known, a user leaves the site, and so on.
    public class SiteVisitors {
    ...
    //user arrives
    public void UnknownVisitorArrived() {
    SessionWrapper.SetUnknownType();
    UnknownVisitorCount++;
    }
    //known user arrives
    public void KnownVisitorArrives() {
    SessionWrapper.SetKnownType();
    KnownVisitorCount++;
    }
    //user logs in
    public void UnknownVisitorLoggedOn() {
    SessionWrapper.SetKnownType();
    UnknownVisitorCount--;
    KnownVisitorCount++;
    }
    //user logs out
    public void KnownVisitorLoggedOut() {
    SessionWrapper.SetUnknownType();
    logged-in userstrackingUnknownVisitorCount++;
    KnownVisitorCount--;
    }
    //user session expires
    public void VisitorLeft() {
    if (SessionWrapper.GetType() ==
    VisitorTypes.KnownVisitor)
    KnownVisitorLeft();
    else
    UnknownVisitorLeft();
    }
    //anon user session expires
    private void UnknownVisitorLeft() {
    UnknownVisitorCount--;
    }
    //logged in user session expires
    private void KnownVisitorLeft() {
    KnownVisitorCount--;
    }
    }
    
  6. With all of these helper functions in place, we are now able to wire our user tracker into our site. We will start by tapping into our application events in the Global.asax. We need to increment our user count when a user comes to the site. We also need to decrement our counts when a user's session expires.

    Note

    Keep in mind that when a user leaves the site, we won't be informed immediately. The session timeout is a value generally set by the web server. Usually, this value is set for 20 minutes. This means that you won't know a user left until 20 minutes after they actually left.

    protected void Session_Start() {
    if(Request.IsAuthenticated)
    SiteVisitors.Instance.KnownVisitorArrives();
    else
    SiteVisitors.Instance.UnknownVisitorArrived();
    }
    protected void Session_End() {
    SiteVisitors.Instance.VisitorLeft();
    }
    
  7. The next place for us to tap into is in the registration, logging in, and logging out code. This code is provided by default in the MVC application, so I used that framework for this recipe. Start by opening up the AccountModels.cs file (Models folder). In there, you will find a few classes and interfaces. Look for the FormsAuthenticationService. This is where the SignIn and SignOut functions can be attached to. For each of those methods, we need to move some of our numbers around, either from known to unknown or unknown to known.
    public class FormsAuthenticationService : IFormsAuthenticationService {
    public void SignIn(string userName, bool createPersistentCookie)
    {
    if (String.IsNullOrEmpty(userName)) throw new ArgumentException("Value cannot be null or empty.", "userName");
    FormsAuthentication.SetAuthCookie(userName, createPersistentCookie);
    SiteVisitors.Instance.UnknownVisitorLoggedOn();
    }
    public void SignOut() {
    FormsAuthentication.SignOut();
    SiteVisitors.Instance.KnownVisitorLoggedOut();
    }
    }
    
  8. With our counter framework in place, we are now ready to display some of the information to our users. We can most easily do this by opening up the Site.Master page and adding to our display for all pages in one shot.
    <div id="logindisplay">
    <% Html.RenderPartial("LogOnUserControl"); %><br />
    Known visitor count: <%: StateExamples.Models.SiteVisitors.Instance
    .KnownVisitorCount %> - Unknown visitor count:
    <%: StateExamples.Models.SiteVisitors.Instance.UnknownVisitorCount %>
    </div>
    
  9. Now you can run the application. The first window that opens up should show that an unknown user is on the site. If you copy the URL and open up a different browser program and paste your URL, you should see that you have two unknown users on the site. Then, in one of the browsers, you can register for a new account. Once you complete the registration process, you should see one unknown user and one known user.
    How to do it...

How it works...

This recipe takes advantage of our application events, session, and the fact that the static instance we get from our singleton class stays accessible during the entire lifetime of the application. With these components, we are able to increment and decrement users from our counts, keep track of the state of users as they move around on our site, and display some stats to our users.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset