Sunday, May 10, 2015

SignalR-based Live Stock Ticker with Ticker.FSharp

Introduction

It was an awesome weekend, finally got my hands into SignalR and updated the Ticker.FSharp to add a SignalR web sample ticker. In this post I have talked about how easy it was to throw a simple ticker together using the Ticker.FSharp repository and SignalR. The sample can be downloaded from the Github repository page.

Screenshot





Implementation

I added an empty web project to the solution, then added a SignalR Hub, a Javascript file for event handling, an HTML page for the UI. Here is a quick overview of each of those.

SignalR Hub

As we know, the server-side hub is a primitive component of a SignalR application. My sample hub has only two methods, one is called by the client to start up the hub when it gets launched the first time, and other method is called from the server side that reports the ticks generated by Ticker.FSharp. The call to Tick then channels in to the browsers of each user connected.

The full source listing for the hub file can be found at this Github page. I am only discussing the important points.

Here is how the Hub is declared

[HubName("tickerFsharp")] public class TickerFSharpHub : Hub
As you can see, the hub declaration contains the HubNameAttribute which tells the SignalR engine how the hub is going to be located. There are two methods inside the hub, one is StartTicker which is responsible for calling the Ticker.FSharp library and obtaining the IObservable<Tick> object. Here I am fetching the ticks of three symbols together.

[HubMethodName("startTicker")]
public void StartTicker()
{
if (subscription == null)
{
var machine = new DataMachine();
var aapl = this.AddIndicator(machine.GetLiveGoogleApiTicks("AAPL"));
var goog = this.AddIndicator(machine.GetLiveGoogleApiTicks("GOOG"));
var msft = this.AddIndicator(machine.GetLiveGoogleApiTicks("MSFT"));

subscription = aapl.Merge(msft).Merge(goog).Subscribe(t => {

this.Tick(t.Tick.Symbol, t.Tick.Price, t.Tick.LastUpdated.ToString(), t.Up);

});.
}

In the above listing, I am calling the Ticker.FSharp 3 times to get the live feed for three symbols. I am also calling the AddIndicator helper method to garnish the object with an additional property that tells me whether the value went up or down since the last value. And finally, I am calling the Tick method which calls the tick method at the client's side.

public void Tick(string symbol, double price, string lastUpdated, bool up)
{
Clients.All.tick(symbol, price.ToString("###0.00"), lastUpdated, up);
}

The above Tick() method implementation is pretty self-explanatory.

Javascript Event Handling

The JS file has quite the code, I am only discussing the tick() handler that server-side will be calling.

hub.client.tick = function (symbol, price, lastUpdated, up) {
var row = $stockTableBody.find("tr[datasymbol=\"" + symbol + "\"]");
if (row.length == 0) {
var templatedRow = rowTemplate.replace("{Symbol}", symbol)
.replace("{Price}", price)
.replace("{lastUpdated}", lastUpdated);
$stockTableBody.append(templatedRow);
}
else {
var cells = row.first().find("td");
cells.eq(0).html(symbol);
cells.eq(1).html(price);
cells.eq(2).html(lastUpdated);
}
}

The above code is simple, as the tick arrives, it checks to see whether the table already has a row for that symbol, if so it updates the data otherwise it adds a new row for that symbol.


Thats all for this blog, if you want to check out the full source code, I encourage you to visit the Github project page.

Happy coding!