WebSync/ExtJS Stock Ticker Example

Click the "Start" button below to publish stock values to this page for 20 seconds. Note that for demonstration purposes, each page receives it's own set of changes to enable individual users to start and stop the demo.

This demo simply demonstrates the capabilities of WebSync. We don't recommend using these numbers to build a portfolio.

How it works

The client

The grid itself is incredibly simple. We started with the ArrayGrid example provided by the excellent developers over at ExtJS. We then made a couple minor modifications:

The server

Next, we set up the server to publish out the rates. We already had WebSync in place from our previous demos, so it was really just a matter of invoking it.

First, we created the data model:

    [DataContract]
    public class Ticker
    {
        [DataMember(Name = "price")]
        public double Price { get; set; }

        [DataMember(Name = "symbol")]
        public string Symbol { get; set; }

        [DataMember(Name = "company", IsRequired = false)]
        public string Company { get; set; }

        [DataMember(Name = "updated")]
        public DateTime Updated { 
            // for the purposes of the demo, updated is always now
            get { return DateTime.Now; } 
            set { } 
        }

        private static List<Ticker> tickers = null;
        public static List<Ticker> GetTickers()
        {
            if (tickers == null)
            {
                tickers = new List<Ticker>();

                tickers.Add(new Ticker() { Price = 72, Symbol = "ATVI", Company = "Activition Blizzard, Inc" });
                tickers.Add(new Ticker() { Price = 72, Symbol = "ADBE", Company = "Adobe Systems Incorporated" }); //
                tickers.Add(new Ticker() { Price = 72, Symbol = "AMZN", Company = "Amazon.com, Inc" }); //Amazon
                tickers.Add(new Ticker() { Price = 72, Symbol = "DELL", Company = "Dell, Inc" }); //Dell
                tickers.Add(new Ticker() { Price = 72, Symbol = "GRMN", Company = "Garmin, Ltd" }); //Garmin
                tickers.Add(new Ticker() { Price = 72, Symbol = "GOOG", Company = "Google Inc" }); //Google
                tickers.Add(new Ticker() { Price = 72, Symbol = "INTC", Company = "Intel Corporation" }); //Intel Corporation
                tickers.Add(new Ticker() { Price = 72, Symbol = "LOGI", Company = "Logitech International S.A." }); //Logitech
                tickers.Add(new Ticker() { Price = 72, Symbol = "MSFT", Company = "Microsoft Corporation" }); //Microsoft
                tickers.Add(new Ticker() { Price = 72, Symbol = "NVDA", Company = "NVIDIA Corporation" }); //Nvidia
                tickers.Add(new Ticker() { Price = 72, Symbol = "ORCL", Company = "Oracle Corporation" }); //Oracle
                tickers.Add(new Ticker() { Price = 72, Symbol = "SBUX", Company = "Starbucks Corporation" }); //Starbucks
                tickers.Add(new Ticker() { Price = 72, Symbol = "YHOO", Company = "Yahoo! Inc" }); //Yahoo
            }
            return tickers;
        }
    }    
    

Then, we added a few lines to publish out some random changes. Not the most efficient in the world, but it does the job:

    List<Ticker> tickers = Ticker.GetTickers();

    int publishes = string.IsNullOrEmpty(Request.QueryString["publishes"]) ? 20 : int.Parse(Request.QueryString["publishes"]);
    string clientId = string.IsNullOrEmpty(Request.QueryString["clientId"]) ? "" : Request.QueryString["clientId"];
    Guid clientGuid = new Guid(clientId);

    WebSyncServer.Notify(new Notification(clientGuid, "{\"publishingRates\": true}"));

    for (int i = 0; i < publishes; i++)
    {
        // keep a list of changed items
        Dictionary<string, Ticker> changed = new Dictionary<string, Ticker>();

        // pick a random number of rates to change
        // always change at least one, but never more than half
        Random random = new Random();
        int limit = random.Next(1, tickers.Count / 2);
        for (int j = 0; j < limit; j++)
        {
            // select the tickers at random. if they overlap, no biggie, since we're caching by symbol
            int index = random.Next(0, tickers.Count);
            // figure out how much we're going to change by. we do +/- up to 2.
            double change = random.Next(-2,2) * random.NextDouble();
            // apply the change
            tickers[index].Price += change;
            // cache the results to ensure a max of 1 message per symbol goes out
            changed[tickers[index].Symbol] = tickers[index];
        }

        // rebuild the list to send to the clients
        List<Ticker> final = new List<Ticker>();
        foreach (KeyValuePair<string, Ticker> pair in changed)
        {
            final.Add(pair.Value);
        }
        
        // send the message out
        WebSyncServer.Publish("/fm/rates/" + clientId, Json.Serialize(final));
        
        // pause for 1/2 a second, then do it again
        System.Threading.Thread.Sleep(500); 
    }
    WebSyncServer.Notify(new Notification(clientGuid, "{\"publishingRates\": false}"));    
    

The JavaScript does a basic XHR request to trigger this and instead of using the request and response to know that we're "publishing" rates, we use the notification mechanism to let the client know when we are ard are not publishing. This more like how you would do this sort of thing in a real project.