DCSIMG
Building ASP.NET Real – time web application – Part 5 - Pini Dayan

Pini Dayan

The best thing about a boolean is even if you are wrong, you are only off by a bit.

Building ASP.NET Real – time web application – Part 5

After seeing the core of the real-time solution in post 1 – 4 this post will show the other code parts and specify a few details and steps we can take to optimize the solution:

So here are the missing codes to complete the puzzle:

The StocksValuesDB class, that simulate a DB being updated in each interval and has an event to tell clients when an update occurs:

public class StocksValuesDB

{

     //The event this DB raised when the data changes

     public delegate void StocksChangedDeleaget(StocksEventArgs args);

     public static event StocksChangedDeleaget OnStocksChanged;

     public static bool Initialized { get; private set; }

     public static int Stock1Value { get; set; }

     public static int Stock2Value { get; set; }

     public static int Stock3Value { get; set; }

     public static int Stock4Value { get; set; }

     public static int Stock5Value { get; set; }

    private static Timer oStocksTimer;

    static StocksValuesDB()

    {

          Initialized = true;

         //Start a timer that simulate a change to the stocks

         oStocksTimer = new Timer();

         oStocksTimer.Interval = 2000;

         oStocksTimer.Elapsed += new ElapsedEventHandler(StocksTimer_Elapsed);

         oStocksTimer.Enabled = true;

         oStocksTimer.Start();

    }

 

    private static void StocksTimer_Elapsed(object sender, ElapsedEventArgs e)

    {

        //Stop the timer and uppdate the stocks

         oStocksTimer.Stop();

  

         Random oRandom = new Random();

         Stock1Value = oRandom.Next(1,1000);

         Stock2Value = oRandom.Next(1, 1000);

         Stock3Value = oRandom.Next(1, 1000);

         Stock4Value = oRandom.Next(1, 1000);

         Stock5Value = oRandom.Next(1, 1000);

         oStocksTimer.Start();

         if(OnStocksChanged != null)

         {

            OnStocksChanged(new StocksEventArgs(Stock1Value, Stock2Value, Stock3Value,

                                           Stock4Value, Stock5Value));

          }

   }

}

The StocksEventArgs class, to be used as the event args for the OnStocksChanged event.

  public class StocksEventArgs : EventArgs

  {

      public StocksValues Stocks;

      public StocksEventArgs(int nStock1Value, int nStock2Value, int nStock3Value, int

            nStock4Value, int nStock5Value)

      {

          Stocks = new StocksValues

                       {

                         Stock1Value = nStock1Value,

                         Stock2Value = nStock2Value,

                         Stock3Value = nStock3Value,

                         Stock4Value = nStock4Value,

                         Stock5Value = nStock5Value

                     };

            }

  }

The StocksValues class, to be passes as a memeber of the event args to the clients.

public class StocksValues

  {

        public int Stock1Value { get; set; }

        public int Stock2Value { get; set; }

        public int Stock3Value { get; set; }

        public int Stock4Value { get; set; }

        public int Stock5Value { get; set; }

  }

The AsyncCallbacksWrapper class, wrapp the AsyncResult object with extra data.

public class AsyncCallbacksWrapper

{

         #region Class members

         //For holding the AsyncResultm for the Async handler

         public AsyncResult<StocksValues> AsyncResult { get; set; }

         //For knowing if it's the same user

         public string SessionID { get; private set; }

         #endregion

 

        #region Class Constructors

        public AsyncCallbacksWrapper(string sSessionID)

        {

          this .SessionID = sSessionID;

        }

        #endregion

}

Te code that I downloaded from the internet and is used as a generic class that implement IAsyncResult can be found in the complete solution file here.

A few important notes:

1. Don’t be afraid if you are getting HTTP 403.9 error, all you need to do is to make sure to abort the timeout request and invoking the handler in case of timeouts or windows close event.If you are using IIS 5.1 you will get it a lot since it is limited to 10 connections.

2. Use TCPView tool to watch what happens on the server and on the client IE.

3. I used a timer to simulate the DB being updated, you can even use SQLCacheDependency

   with polling or notification services ( I tried it it worked).

4. Use the AsyncCallbacksWrapper to add more properties to be filtered later. Instead

   of waiting all the client in case of an updat , you can filter the clients that are

   interested in this event or even filder the Data being returned to them.

Enjoy.

 

Comments

Ric said:

Excellant Posts. One Q. How do you pass a parameter into the actual worker Class StocksValuesDB? Say we wanted to monitor 1 stock, or a list of stocks, in you example?

In my implementation I need to pass a StationID into my equivelant of StocksValuesDB. I was able to pass it as q QS parameter to the ashx. How do I get it into StocksValuesDB?

A response would be greatly appreciated!

# February 25, 2010 2:04 PM

Pini Dayan said:

Hi Ric,

Will glad to answer.

In my sample I am initializing this class using a static contructor

You can simply create another class instead of this with a normal contrutor or setter functions and initialize it when the application loads for the first time (application_start?)

# February 28, 2010 10:26 AM

Shane said:

Really great posts. Would it become a standard ASP.NET feature in the future official Microsoft release?

# March 18, 2010 2:01 PM

Pini Dayan said:

Thanks Shane!

Dont know :-)

# March 21, 2010 8:51 AM
Leave a Comment

(required) 

(required) 

(optional)

(required) 


Enter the numbers above: