- Posted by dan on January 13, 2013
Exciting happenings, the bosses at 7digital decided that my team (Payments) and the Locker team were just to awesome for the main office and that they needed to put us in TechHub until such time as our shiny new office is ready. So to TechHub we moved.
To mark the occassion we made a silly little video following our team mascot The Pig (Payments team Piggy bank yeah you got it), to the new office.
The Pig
We have a support person on our team and the responsibility rotates round to a different team member every week. I've previously referred to this role as the "Batman". To give other teams or customers an idea of who the right person to come up and ask is we usually have some sort of label graphic sign. Our team got "The Pig" Say it the way Jeremy Clarkson says "The Stig" and you'll get the full affect.

- Posted by dan on October 21, 2011
What we'll be doing
We're going to do a basic quickstart tutorial on building a realtime webappliction using SignalR. SignalR is hosted on GitHub and makes it easy to push messages from the server to the client browsers. We'll be simply flling out a form to add a story div to the current page, KnockoutJs and SignalR source code download is here.
SignalR Sceencast (see written tutorial below)
SignalR Tutorial
For this app you'll need Visual Studio 2010 with SP1 and Asp.Net MVC 3 package installed. We also assume you've got NuGet installed, if you haven't install NuGet.
Step 1 - Create an Empty Asp.Net MVC 3 App
Goto File --> New Project --> Web --> Asp.Net MVC 3 Application (Make sure it's .Net Framework 4). Call your project something interesting like SignalRTutorial .
Firstly let's just check everything compiles and we indeed have an empty web application. We're going to break the tradition and make a Scrum board. This is partially to try and keep me more organised in the new year.
Step 2 - Add SignalR Package
Right click on references and click Manage NuGet Packages. Search for SignalR and click install. Just check everything compiles before we start.

Step 3 - Create a StoryCard Class
Minor part but this will be our simple DTO (Data Transfer Object) that we'll pass between the server and browser.
using SignalRTutorial.Hubs;
namespace SignalRTutorial.Models
{
public class StoryCard
{
public string Title { get; set; }
public string Description { get; set; }
public StoryState State { get; set; }
public int Id { get; set; }
public static StoryCard Create(string title, string description, StoryState storyState)
{
return new StoryCard
{
Id=1,
Title = title,
Description = description,
State = storyState
};
}
}
}
namespace SignalRTutorial.Models
{
public enum StoryState{Todo,InProgress,Verify,Done}
}
Step 4 - Create a SignalR Hub
Create a new class called ScrumBoardHub and inherit from Hub this lets SignalR work it's magic.
using System.Collections.Generic;
using SignalR.Hubs;
using SignalRTutorial.Models;
namespace SignalRTutorial.Hubs
{
public class ScrumBoardHub : Hub
{
private readonly IScrumRepository _repository;
public ScrumBoardHub():this(new ScrumBoardRepository()){}
public ScrumBoardHub(IScrumRepository repository)
{
_repository = repository;
}
public void CreateStory(StoryCard story)
{
Caller.AddedStory(story);
}
public void GetStories()
{
var storyCards = new List()
{
new StoryCard
{
Id = 1, Title = "Story 1", Description = "Story 1 desc", State = StoryState.Todo
}, new StoryCard
{
Id = 2, Title = "Story 2", Description = "Story 2 desc", State = StoryState.Todo
},
};
var array = storyCards.ToArray();
Caller.populateStories( array);
}
}
}
Step 5 - Create a Board Listing Page
I've just used the index page from the HomeController. Below are the various bits of Javascript you'll need for this to work. Please pay particular attentiaon to KnockoutJs and Jquery.signalr-0.5.3.js

Just above is the line that will thanks to a bit of KnockoutJs magic our list of stories. We're using the data-bind attribute but this time we're specifying a template called story-template.
Then we simply tell it to bind to stories property on our ScrumBoard viewModel which you'll see defined below in the javascript.

Step 6 - wireup KnockoutJs model binding with SignalR
Below is the Javascript for mapping our StoryCard object on the server side to a Story client side object. We have a Scrumboard object that exposes a few methods including binding itself to the title and description fields for adding new stories. When the form is submitted, addStory is called which in turn calls createStory on the SignalR hub. On the serverside we then use SignalR to call out to the addedStory javascript method which simply creates a new instance of a Story in the javascript and adds it onto the stories collection.
KnockoutJs then uses it's model binding, to add another div to the container, as indicated by the foreach binding above.
$(function () {
function Story(id, title, description, state) {
this.Id = ko.observable(id);
this.Title = ko.observable(title);
this.Description = ko.observable(description);
this.State = ko.observable(state);
}
function ScrumBoard() {
this.title = ko.observable("New Story");
this.description = ko.observable("New Description");
this.hub = $.connection.scrumBoardHub;
this.viewModel = null;
this.stories = ko.observableArray([]);
var stories = this.stories;
this.init = function () {
console.log("init");
this.hub.getStories();
};
this.addStory = function (newStory) {
console.log("addStory");
var t = { "title": this.title(), "description": this.description(), "state":"todo" };
this.hub.createStory(t).done(function () {
console.log('Success!')
}).fail(function (e) {
console.warn(e);
});
this.title("");
this.description("");
};
this.hub.addedStory = function (story) {
console.log("addedStory");
stories.push(new Story(story.Id, story.Title, story.Description,story.State));
};
this.hub.populateStories = function (storyArray) {
console.log("populate stories");
var mappedTasks = $.map(storyArray, function (item) {
return new Story(item.Id, item.Title, item.Description,item.State);
});
stories(mappedTasks);
};
}
var scrumBoard = new ScrumBoard();
$.connection.hub.start(function () { scrumBoard.init(); });
ko.applyBindings(scrumBoard);
});
Conclusion
That's it. Isn't that cool, we could improve it by also storing stories in a database using NHibernate, and we can further scale it by utilising Redis. I'll embelish later
References
Testing SignalR Tutorial
The Source code for this tutorial
https://github.com/SignalR/SignalR
Scott Hanselman's SignalR Tutorial
AmazedSaint - RealTime TaskPad with SignalR and KnockoutJS
SignalR and KnockoutJs Realtime task list