Stefan's profileStefan Prodan's spacePhotosBlogLists Tools Help

Blog


    Session provider for .NET Remoting and WCF

    Project objectives
    Create a session provider mechanism that mimics the ASP.NET Session. The provider target are distributed applications developed with VS.NET 2008 and .NET Framework 3.5. The Session object should be compatible with .NET Remoting and WCF technologies and must perform well in a multithreading environment. The Session provider should be customize by external components without recompilation.

    Project background
    The project was first developed on .NET Framework 2.0 and was used by a distributed application made with C# 2.0 and .NET Remoting. Now the application is run by over 2000 clients with good feedback, no bugs have been reported regarding the features that depend on the Session component. The reason behind the C# 3.0 upgraded version of the Session component is the fact that due to the multithreading environment the C# 2.0 version was using the ReaderWriterLock class. ReaderWriterLock has a lot of problems in environments with heavy load, .NET Framework 3.5 brings a new class named ReaderWriterLockSlim that improves speed and reduces the deadlock occurrence possibilities. You can find out more about the reasons why Microsoft decided to implement the ReaderWriterLockSlim from the Joe Duffy's Blog in this post and you can see a performance comparison of ReaderWriterLockSlim with ReaderWriterLock on Pedram Razaei's blog in this post. The older version of the Session project has allot of hard coded members, members that were application specific, the new version has to provide a way to add dynamic objects to the Session, objects that are not implemented inside the Session class.

    Building interfaces
    To reach one of the main objective(extensibility) I've created an interface for the objects that can register in the session instance. All objects that can register must implement the ISessionEntry. By this interface the Session provider can control the entries and in the same time the developer can create his own class that suits his needs without changing the Session class code.
    ISessionEntry

    Another interface used in the project is ISession. If you want to have your own implementation of the Session provider you can do it by inheriting ISession. Note that T is type of ISessionEntry and must have a default empty constructor.

    public interface ISession<T> where T : ISessionEntry, new()

    ISession

    Building Session class
    The full code of the Session class can be found here, but let me explain a little what's going on. The Session class is ensuring the thread safety of it's members using a ReaderWriterLockSlim instance called slimLoack. There are 3 collections inside that holds the objects managed by the class: activEntries, expiredEntries and data. The activEntries collection is most important one, to modify this List there 2 public methods (Register and Unregister) and one private method named ClearExpired that's called by the cleaner thread every minute. The expiredEntries is a private collection used by the cleaner thread inside ClearExpired and helps delete entries from the active collection.

    public Session(int sessionTimeoutInMinutes)
    {
    slimLock = new ReaderWriterLockSlim();
    cleaner = new Thread(new ParameterizedThreadStart(ClearExpired));
    cleaner.IsBackground = true;
    cleaner.Start(sessionTimeoutInMinutes);
    }

    As you can see in the constructor it can be set the timeout, there is no default value like in ASP.NET (20 minutes) because I think that any .NET Remoting server or WCF has it's own specific timeout, for example in the distributed application I mentioned the timeout is like 1h but if your application has per user licence then the timeout should be very short. In a per user licence case you should make on the client a KeepAlive Thread that every minute updates the LastAccessTime value on the server using the public method UpdateLastAccessTime. If the client shuts down without calling the Unregister method then after 1 minute he can login again because the cleaner thread has deleted the user entry from the active session.
    The data collection is of type Dictionary<long, Hashtable> and mimics the ASP.NET way of storing and retrieving custom objects from the session. There is a Set and a Get method, in order to perform them the objects stored must be marked as serializable, if you'll use binary serialization in Remoting or netTcpBinding in WCF most of the objects will be suitable for session storage.
    There is a method named PrepareForDispose, it's not a common method for a .NET class but I wanted to make sure that the cleaner thread will exist gracefully, calling Abort on a thread is very nasty way to exit because it will throw a ThreadAbortException. So my PrepareForDispose method wakes up the thread if it's in sleep mode and waits for it to finish processing like this:

    //set volatile flag
    running = false;
    //wake up cleaner if (cleaner.ThreadState == ThreadState.WaitSleepJoin)
    {
    cleaner.Interrupt();
    }
    //wait for the thread to stop for (int i = 0; i < 100; i++)
    {
    if (cleaner == null || cleaner.ThreadState == ThreadState.Stopped)
    {
    System.Diagnostics.Debug.WriteLine(
    "Cleaner has stopped after " + i * 100 + " milliseconds");
    break;
    }
    Thread.Sleep(100);
    }

    Using the Session provider
    Before using the the Session provider we have to create a class suitable for a session entry, the most common usage is the User class.

    [Serializable]
    public sealed class User : ISessionEntry
    {
    #region ISessionEntry Members
    public long SessionId
    { get; set; }

    public DateTime LastAccessTime
    { get; set; }
    #endregion public string Username
    { get; set; }
    public string Password
    { get; set; }
    }

    The following example is a console application and it shows how the methods of Session class can be used:

    class Program
    {
    static void Main(string[] args)
    {
    //Session object creation Session<User> sessionManager = new Session<User>(1);
    //Register timeout event sessionManager.OnEntryTimeout += new SessionEntryTimeoutDelegate<User>(sessionManager_OnEntryTimeout);
    //New user User user = new User() { Username = "Stefan", Password = "Prodan" };
    //Login sessionManager.Register(ref user);
    //Call Session specific methods Console.WriteLine("User {0} session id is {1}",
    sessionManager[user.SessionId].Username, user.SessionId);
    //Store on the session a user's object sessionManager.SetData("MyData", "UserObject", user.SessionId);
    Console.WriteLine("{0} session data is {1}",
    user.Username, sessionManager.GetData("MyData", user.SessionId));
    //Wait for the user session to expire Console.WriteLine("Wait until the session expires (1 minute)");
    Console.ReadKey();
    //Free resources used by the session sessionManager.PrepareForDispose(); Console.ReadKey(); } static void sessionManager_OnEntryTimeout(User user)
    {
    Console.WriteLine("Session expired for user id {0}", user.SessionId);

    }
    }

    In the future I will post real examples of how to use Session provider in production with .NET Remoting and WCF. Full source code of the examples will be uploaded to my SkyDrive public folder so anyone can get them. In the meanwhile I am expecting comments and ideas about improving the session provider.

    Digg!

    kick it on DotNetKicks.com

    Comments (10)

    Please wait...
    Sorry, the comment you entered is too long. Please shorten it.
    You didn't enter anything. Please try again.
    Sorry, we can't add your comment right now. Please try again later.
    To add a comment, you need permission from your parent. Ask for permission
    Your parent has turned off comments.
    Sorry, we can't delete your comment right now. Please try again later.
    You've exceeded the maximum number of comments that can be left in one day. Please try again in 24 hours.
    Your account has had the ability to leave comments disabled because our systems indicate that you may be spamming other users. If you believe that your account has been disabled in error please contact Windows Live support.
    Complete the security check below to finish leaving your comment.
    The characters you type in the security check must match the characters in the picture or audio.

    To add a comment, sign in with your Windows Live ID (if you use Hotmail, Messenger, or Xbox LIVE, you have a Windows Live ID). Sign in


    Don't have a Windows Live ID? Sign up

    1 Nov.
    26 Oct.
    No namewrote:

    Hi,Do you need digital signages, advertising displays, digital sign, advertisement displays and advertising players? Please go Here:www.amberdigital.com.hk(Amberdigital).we have explored and developed the international market with professionalism. We have built a widespread marketing network, and set up a capable management team dedicated to provide beyond-expectation services to our customers.

    amberdigital Contact Us

    website:www.amberdigital.com.hk
    alibaba:amberdigital.en.alibaba.com[ieb

    17 Oct.
    No namewrote:

    Hi,Do you need advertising displays, advertisement screens, LCD digital signage and LCD signages? Please go Here:www.amberdigital.com.hk(Amberdigital).we have explored and developed the international market with professionalism. We have built a widespread marketing network, and set up a capable management team dedicated to provide beyond-expectation services to our customers.

    amberdigital Contact Us

    website:www.amberdigital.com.hk
    alibaba:amberdigital.en.alibaba.com[gedihfieichdjh]

    23 Sept.
    No namewrote:
    To the global wow gold the cheapest wow power leveling under the cheapest single-site! -41755239030599
    16 Sept.
    No namewrote:
    Be wow gold cheapest wow power leveling under the best single-site!
    15 Sept.
    No namewrote:

    Amberdigital Branch,Southern Stars Enterprises Co is specializing in the development and manufacturing of advertisement screens, LCD digital signage and LCD signages. Established in 1996, we have explored and developed the international market with professionalism. We have built a widespread marketing network, and set up a capable management team dedicated to provide beyond-expectation services to our customers.

    amberdigital Contact Us
    Southern Stars Enterprises Co (Hong Kong Office)
    Add:3 Fl, No.2, Lane 2, Kam Tsin Tsuen, Sheung Shui, Hong Kong
    Tel:+852 2681 4099
    Fax:+852 2681 4586

    Southern Stars Enterprises Co (Shenzhen Office)
    Add:DE, 16/F, Building 2, Nanguo Tower, Sungang Road, Shenzhen, China
    Tel:+86 755 2592 9100
    Fax:+86 755 2592 7171

    E-mail:sstar@netvigator.com
    website:www.amberdigital.com.hk
    alibaba:amberdigital.en.alibaba.com[abgcdabbhdcich]

    27 Aug.
    No namewrote:
    Welcome (wow gold) and (wow power leveling) trading site, (wow gold) are cheap, (wow power leveling) credibility Very good! Quickly into the next single! Key words directly to the website click on transactions!
    18 Aug.
    Picture of Anonymous
    Leandro M wrote:
    Hi,
    Thank you for this great article ...
     
    Do you think you could show us how to use it with WCF ?
     
    Thanks and keep up with the good work !
    18 May
    No namewrote:
    >In the future I will post real examples of how to use Session provider in production with .NET Remoting and WCF. Full source code of >the examples will be uploaded to my SkyDrive public folder so anyone can get them. In the meanwhile I am expecting comments >and ideas about improving the session provider.
     
    Hi, Stefan. I cant find your SkyDrive, could you give me the link?
     
    24 Jan.

    Trackbacks

    The trackback URL for this entry is:
    http://stefanprodan.spaces.live.com/blog/cns!51631701627C9BD0!164.trak
    Weblogs that reference this entry
    • None