Maarten Balliauw {blog}

ASP.NET, ASP.NET MVC, Windows Azure, PHP, ...


TechDays Finland - Architectural Patterns for the Cloud - NuGet

As promised, here are the slide decks for the two sessions delivered at TechDays Finland last week.

Architectural Patterns for the Cloud

The promise of all cloud vendors out there is they can run your applications without changes. While that claim is true, it’s better to optimize existing software or design specifically for the cloud when moving or building an application. Architectural optimization will speed up your application, make it more scalable and even will make it cheaper to run on Windows Azure. This session will take you along some common patterns that are easy to implement and will make your cloud more sunny.

Organize your Chickens - NuGet for the Enterprise

Managing software dependencies, whether those created in-house or from third parties can be a pain in the behind. Whether dependencies feel like wild chickens or people run around like chickens dealing with dependencies, the NuGet package manager can be a cure. Let us guide you to creating enterprise (chicken) NuGets and dealing with them in a structured, easy-to-maintain manner. From developer workstation to build server, NuGet tastes great! We'll provide you the dip sauce.

Enjoy! And if there’s any feedback or questions, I would love to hear it.

Introducing MyGet package source proxy (beta)

My blog already has quite the number of blog posts around MyGet, our NuGet-as-a-Service solution which my colleague Xavier and I are running. There are a lot of reasons to host your own personal NuGet feed (such as protecting your intellectual property or only adding approved packages to the feed, but there’s many more as you can <plug>read in our book</plug>). We’ve added support for another scenario: MyGet now supports proxying remote feeds.

Up until now, MyGet required you to upload your own NuGet packages and to include packages from the NuGet feed. The problem with this is that you either required your team to register multiple NuGet feeds in Visual Studio (which still is a good option) or to register just your MyGet feed and add all packages your team is using to it. Which, again, is also a good option.

With our package source proxy in place, we now provide a third option: MyGet can proxy upstream NuGet feeds. Let’s start with a quick diagram and afterwards walk you through a scenario elaborating on this:

MyGet Feed Proxy Aggregate Feed Connector

You are seeing this correctly: you can now register just your MyGet feed in Visual Studio and we’ll add upstream packages to your feed automatically, optionally filtered as well.

Enabling MyGet package source proxy

Enabling the MyGet package source proxy is very straightforward. Navigate to your feed of choice (or create a new one) and click the Package Sources item. This will present you with a screen similar to this:

MyGet hosted package source

From there, you can add external (or MyGet) feeds to your personal feed and add packages directly from them using the Add package dialog. More on that in Xavier’s blog post. What’s more: with the tick of a checkbox, these external feeds can also be aggregated with your feed in Visual Studio’s search results. Here’s the magical add dialog and the proxy checkbox:

Add package source proxy

As you may see, we also offer the option to filter upstream packages. For example, the filter string substringof('wp7', Tags) eq true that we used will filter all upstream packages where the tags contain “wp7”.

What will Visual Studio display us? Well, just the Windows Phone 7 packages from NuGet, served through our single-endpoint MyGet feed.


Instead of working with a number of NuGet feeds, your development team will just work with one feed that is aggregating packages from both MyGet and other package sources out there (NuGet, Orchard Gallery, Chocolatey, …). This centralizes managing external packages and makes it easier for your team members to find the packages they can use in your projects.

Do let us know what you think of this feature! Our UserVoice is there for you, and in fact, that’s where we got the idea for this feature from in the first place. Your voice is heard!

Slides for TechDays Belgium 2012: SignalR

It was the last session on the last day of TechDays 2012 so I was expecting almost nobody to show up. Still, a packed room came to have a look at how to make the web realtime using SignalR. Thanks for joining and for being very cooperative during the demos!

As promised, here are the slides. You can also find the demo code here: SignalR. Code, not toothpaste - TechDays Belgium (2.74 mb)

A recording on Channel9 is available as well.

PS: The book on NuGet (Pro NuGet) which I mentioned can be (pre)ordered on Amazon.

Slides for UGIALT.NET - SignalR

Except for having a bad, bad experience using EasyJet on the way towards Milan, UGIALT.NET was a blast! Here's the slide deck and sample code for my session on SignalR.

Abstract: "SignalR. Code, not toothpaste. (or: Using SignalR for realtime client/server communication) Today’s users are interested in a rich experience where the terms client and server don’t mean a thing. They expect real-time action between both, no matter if the technology used is HTML5 websockets or something else. This session will cover SignalR and show you how it can be used to communicate in real time between the client and server, using HTML5 or not. Combine SignalR with ASP.NET MVC, jQuery and perhaps a sprinkle of Windows Azure and you’ll have an interesting, reliable and fast stack to build your real-time client-server and server-client communications. Join me on this journey between web, cloud and user. No toothpaste. Just code."

Demo code is available for download as well: (1.68 mb)

PS: EasyJet was kind enough to provide us with a flight attendant that looked and talked like Borat on the flight back, which made me laugh numerous times during the flight. Is nice!

Tracking API usage with Google Analytics

So you have an API. Congratulations! You should have one. But how do you track who uses it, what client software they use and so on? You may be logging API calls yourself. You may be relying on services like who make you pay (for a great service, though!). Being cheap, we thought about another approach for MyGet. We’re already using Google Analytics to track pageviews and so on, why not use Google Analytics for tracking API calls as well?

Meet GoogleAnalyticsTracker. It is a three-classes assembly which allows you to track requests from within C# to Google Analytics.

Go and  fork this thing and add out-of-the-box support for WCF Web API, Nancy or even “plain old” WCF or ASMX!

Using GoogleAnalyticsTracker

Using GoogleAnalyticsTracker in your projects is simple. Simply Install-Package GoogleAnalyticsTracker and be an API tracking bad-ass! There are two things required: a Google Analytics tracking ID (something in the form of UA-XXXXXXX-X) and the domain you wish to track, preferably the same domain as the one registered with Google Analytics.

After installing GoogleAnalyticsTracker into your project, you currently have two options to track your API calls: use the Tracker class or use the included ASP.NET MVC Action Filter.

Here’s a quick demo of using the Tracker class:

1 Tracker tracker = new Tracker("UA-XXXXXX-XX", ""); 2 tracker.TrackPageView("My API - Create", "api/create");

Unfortunately, this class has no notion of a web request. This means that if you want to track user agents and user languages, you’ll have to add some more code:

1 Tracker tracker = new Tracker("UA-XXXXXX-XX", ""); 2 3 var request = HttpContext.Request; 4 tracker.Hostname = request.UserHostName; 5 tracker.UserAgent = request.UserAgent; 6 tracker.Language = request.UserLanguages != null ? string.Join(";", request.UserLanguages) : ""; 7 8 tracker.TrackPageView("My API - Create", "api/create");

Whaah! No worries though: there’s an extension method which does just that:

1 Tracker tracker = new Tracker("UA-XXXXXX-XX", ""); 2 tracker.TrackPageView(HttpContext, "My API - Create", "api/create");

The sad part is: this code quickly clutters all your action methods. No worries! There’s an ActionFilter for that!

1 [ActionTracking("UA-XXXXXX-XX", "")] 2 public class ApiController 3 : Controller 4 { 5 public JsonResult Create() 6 { 7 return Json(true); 8 } 9 }

And what’s better: you can register it globally and optionally filter it to only track specific controllers and actions!

1 public class MvcApplication : System.Web.HttpApplication 2 { 3 public static void RegisterGlobalFilters(GlobalFilterCollection filters) 4 { 5 filters.Add(new HandleErrorAttribute()); 6 filters.Add(new ActionTrackingAttribute( 7 "UA-XXXXXX-XX", "", 8 action => action.ControllerDescriptor.ControllerName == "Api") 9 ); 10 } 11 }

And here’s what it could look like (we’re only tracking for the second day now…):

WCF Web API analytics google

We even have stats about the versions of the NuGet Command Line used to access our API!

NuGet API tracking Google

Enjoy! And fork this thing and add out-of-the-box support for WCF Web API, Nancy or even “plain old” WCF or ASMX!

Don’t brag about your Visual Studio achievements! (yet?)

imageThe Channel 9 folks seem to have released the first beta of their Visual Studio Achievements project. The idea of Visual Studio Achievements is pretty awesome:

Bring Some Game To Your Code!

A software engineer’s glory so often goes unnoticed. Attention seems to come either when there are bugs or when the final project ships. But rarely is a developer appreciated for all the nuances and subtleties of a piece of code–and all the heroics it took to write it. With Visual Studio Achievements Beta, your talents are recognized as you perform various coding feats, unlock achievements and earn badges.

Find the announcement here and the beta from the Visual Studio Gallery here.

The bad

The idea behind Visual Studio Achievements is awesome! Unfortunately, the current achievements series is pure crap and will get you into trouble. A simple example:

Regional Manager (7 points)

Add 10 regions to a class. Your code is so readable, if I only didn't have to keep collapsing and expanding!

Are they serious? 10 regions in a class means bad code design. It should crash your Visual Studio and only allow you to restart it if you swear you’ll read a book on modern OO design.

Another example:

Job Security (0 points)

Write 20 single letter class level variables in one file. Kudos to you for being cryptic! Uses FxCop

While I’m sure this one is meant to be sarcastic (hence the 0 points), it makes people write unreadable code.

There’s a number of bad coding habits in the list of achievements. And I really hope no-one on my team ever “achieves” some items on that list. If they do, I’m pretty sure that project is doomed.

The good

The good thing is: there are some positive achievements. For example, stimulating people to organize usings. Or to try out some extensions. Unfortunately, there are almost no “good” achievements. What I would like to see is a bunch more extensions that make it fun to discover new features in Visual Studio or learn about good coding habits.

Don’t get me wrong: I do like the idea of achievements very much. In fact, I feel an urge to have the Go To Hell achievement (and delete the code afterwards, promise!), but why not use them to teach people to be better at coding or be more productive? How about achievements that stimulate people to use CTRL + , which a lot of people don’t know about. Or teach people to write a unit test. Heck, you can even become Disposable by correctly implementing IDisposable!

So in conclusion: your resume will look very bad if you are a Regional Manager or gained the Turtles All The Way Down achievement. Don’t brag about those. Come up with some good habits that can be rewarded with achievements and please, ask the Channel 9 guys to include those.

[edit]This one does have positive achievements: [/edit]
[edit] [/edit]

How do you synchronize a million to-do lists?

Not this question, but a similar one, has been asked by one of our customers. An interesting question, isn’t it? Wait. It gets more interesting. I’ll sketch a fake scenario that’s similar to our customer’s question. Imagine you are building mobile applications to manage a simple to-do list. This software is available on Android, iPhone, iPad, Windows Phone 7 and via a web browser. One day, the decision to share to-do lists has been made. Me and my wife should be able to share one to-do list between us, having an up-to-date version of the list on every device we grant access to this to-do list. Now imagine there are a million of those groups, where every partner in the sync relationship has the latest version of the list on his device. In often a disconnected world.

How would you solve this?

My take: Windows Azure Service Bus Topics & Subscriptions

According to the Windows Azure Service Bus product description, it “implements a publish/subscribe pattern that delivers a highly scalable, flexible, and cost-effective way to publish messages from an application and deliver them to multiple subscribers.“ Interesting. I’m not going into the specifics of it (maybe in a next post), but the Windows Azure Service Bus gave me an idea: why not put all actions (add an item, complete a to-do) on a queue, tagged with the appropriate “group” metadata? Here’s the producer side:

Windows Azure Service Bus Topics

On the consumer side, our devices are listening as well. Every device creates its subscription on the service bus topic. These subscriptions are named per device and filtered on the SyncGroup metadata. The Windows Azure Service Bus will take care of duplicating messages to every subscription as well as keeping track of messages that have not been processed: if I’m offline, messages are queued. If I’m online, I receive messages targeted at my device:

Windows Azure Service Bus Subscritpions

The only limitation to this is keeping the number of topics & subscriptions below the limits of Windows Azure Service Bus. But even then: if I just make sure every sync group is on the same bus, I can scale out over multiple service buses.

How would you solve the problem sketched? Comments are very welcomed!

Predictions for the future

It’s almost the end of 2011. Typically a time where bloggers start to write about their past year and what they’ll do in the next. A time where the Forrester, Gartner and McKinsey-alikes make predictions about next year. I know, normally I blog about technology in its technological sense, but today I feel like blogging about my vision on the future. Not 2012, but the future. And the present. Here’s my story in which I try to capture todays world and how this will influence technology.

The world in which we work

Let’s start with some context. I live in the wonderful country of Belgium. A small country, known for its fine chocolates and more importantly: its massive amount of fine brews like Trappists (nothing beats Rochefort 10!). Unfortunately, we are now also known and will probably end up in the Guinness Book of World Records as the country having the longest negotiations to form a government. Around 540 days between voting and formation. (and these guys now have Christmas holidays, of course). But I digress. This country is also a small part in the European crisis which involves monetary issues, banking crisis and so on. The reason? People who don’t want to take responsibilities for their actions. People who don’t want to see change, as they are in a good position. Or people who do want changes but enforce changes that are based on short-term vision. Or tunnel vision: some data required to make decisions does never ever bubble up to higher management (or isn’t cared about).

I know, this post starts to feel like a governmental rant but it isn’t. There’s more to this story: it involves all of us. It involves every single corporation with management levels and focused on making money. The problem is: the larger these companies (or countries, too) get, the more overhead is involved. This is a required step though: you don’t want your CEO to micro-manage everything, the poor guy would have no sleep, ever. What is wrong though, is most of these processes (or laws) come in place and are never optimized. Where processes should support the business in its goals, a lot of processes evolve from supporting to “business prevention”. In fact, I believe in every single country and/or enterprise, a lot of business prevention units and processes exist. And I wouldn’t be surprised that this number is a lot higher than the number of rules that support the business. I’m not saying all of this is happening intentionally, but it is happening.

I’ll give you a fine example of something I witnessed earlier and triggered me into finally writing this post. Someone at some company in a role that involves experimenting with “unapproved” tools, required a simple, clean virtual machine. A process was in place: the request for a VM should be motivated (why do you want this?). Not a problem: the why is easy. Future earnings by investing in some research. Unfortunately, the guys executing this process (your typical IT department) had several other questions. Why isn’t this approved tooling and applications? What resources do you need -oh- that’ll be difficult. Demotivation from the people executing this process. Why? Because they, too, don’t want to follow the food chain up through the organization to ask for an internal budget of, say, 250 EUR per month. A budget that already was spent informally by e-mailing and calling back-and-forth instead of just getting the damn VM in place. In fact, those external hosters with a VM for 25 EUR / month seemed attractive. 25 EUR, or even 250 EUR, for a potential future business idea? An idea that costs almost nothing but may (or may not, it depends) offer return in the future. A budget that has already been spent by just preventing this idea from happening.

Meet the next generation of workers. Many people entering these large enterprises (or becoming residents of countries, again, the same ideas apply for any organization involving more than a few people) are disappointed. Disappointed with the fact that their ideals (making the entire group of ants move forward) is tempered by that same group of ants working in the opposite direction. And the thing is: this group of ants will keep doing this as long as other groups of ants throw some meat into the ant pile. Money.

Earlier this year we’ve seen protests around the world. The Middle East protests, Occupy movements, … All sorts of people fighting against their pile of ants. In some cases this will work, in some probably not. The same happens in enterprises: people fight these business prevention processes but are fighting a fight that will never work. That’s why management layers and business prevention processes are in place.

This story may sound depressing but it isn’t. There are new ants growing to the top and more fresh ants are entering the higher regions of these management layers and business prevention units. They too are frustrated with things not happening, just because. They are trying to change all this. But unfortunately, the pace in which this happens is slow? Utterly slow.

The flipside

We are on the flipside. Companies in technology, very much focused on small layers of overhead and business prevention, are introducing new products and technologies. Tablets, “apps”. The Internet. Telecommuting as a solution to those traffic jam that only cost money and create stress and health problems. But not everyone is in that world. Yet.

People will become more vocal, that’s what we’ve seen with all the protesting. People will want to bring their own hardware to work (because it’s faster than that crappy Windows XP machine they are forced to use). People will bring tablets. People will want to work distributed, when they want and where they want. People will start placing their own goal at the same level of the goal the group of ants has: they’ll strive for personal happiness and at the same time meat for the group of ants. But in order to achieve those two goals, they’ll force change. They’ll want to get rid of business prevention processes because they cost time. And losing time means losing moments to enjoy family and friends. And the group of ants loses at the same time, too.

Now how will this change happen? Well, through consumerization and technology. Over the last years, we’ve seen people adopting the Internet. Desktops are being replaced by laptops, smartphones and tablets. People want their favorite tools, in which they can work most efficient. Just like people wearing orange socks instead of black socks. People will want to be more efficient, and their tools at hand make them feel efficient. And this continues at a higher pace than before: I see a lot of people running around with tablets. I see smartphones being used. I see social media being used as a focused and immediate communication channel to get things organized. Much like the consumerization of the governments in the Middle East, consumerization in enterprises will happen. Be prepared and focus on these things:

  • People will bring their own devices. They’ll bring in the right tool for the job. A tablet? Sure. A web browser on any device? Why not. As a company, better start preparing to become an ISP for your employees instead of an IT department doing nothing but blacklisting. People are used to this at home, so why not in the world they work in? Prediction 1: Bring your own device.
  • In my example earlier: people want to keep their pace. Why fight when all you need is a credit card to open up a cloud somewhere? Employees will do this. Managers as well: they too feel the fight and see easier, more efficient ways out. Why remove “your inbox is almost full” e-mails daily when there’s 25 GB of inbox space waiting to be unlocked for 5 EUR / month? Prediction 2: Cloud momentum will rise.
  • Silverlight is dead? The Web is dead? Apps are dead? If you’ve followed Twitter these days, those predictions were made. I say: nonsense. I see things converge. Smaller, less bloated but more agile ways of working, whether if it’s trough a small app or through a small, focused website. The actual technology will not matter, the way people work with it will. Prediction 3: UX and how we use apps will matter, technology will be supportive.
  • People want to work together. Move forward, together. One way of doing that is to open up your silos. Create API’s which focus on exposing information. Don’t focus on the software consuming those. Maybe it’s better to create an API instead of creating an extranet application. Let the consumers decide how they’ll work with that data. Prediction 4: API’s.
  • Some business models are dead. Large enterprises still exist because money keeps flowing in. But what if the consumerization stops that? Look at the music industry. People wanted fast and easy access to their music. Nothing happened in the industry. Consumers did their thing and invented things like Napster. Until one company with a fruit logo was smart enough to see a business model in this. Be prepared. Consumers, be it in their personal or work life, may no longer be happy with your business model. They’ll request change or change it themselves. If you don’t, you’ll end up like the music industry, fighting a fight that you can never win. The book industry got it right: they changed the way books are being distributed to e-book readers. Sure, there are alternative and illegal ways to read a book, but they are winning their fight. Small change but supporting the consumer. Prediction 5: Business and revenue models will (have to) change.
  • Smaller projects. You probably know those two-year projects were a lot of stuff gets analyzed and implemented. Project fails. 2 years of money and effort wasted. But since we don’t want to see this failure bubble up or down means that we do put this thing in production. Which forces users to start consumerizing faster. The return of the MS Access database! Prediction 6: Projects will become smaller and more focused.

Those are my predictions. And all are the result of consumerization and technology enabling people. I don’t know if 2012 will bring all of these. I do think some of them will start emerging. Be prepared for change.

PS: I promise, my next blog post will be about angle brackets again.

PS 2: I am not targeting any specific government or specific enterprise.

Using SignalR to broadcast a slide deck

imageLast week, I’ve discussed Techniques for real-time client-server communication on the web (SignalR to the rescue). We’ve seen that when building web applications, you often face the fact that HTTP, the foundation of the web, is a request/response protocol. A client issues a request, a server handles this request and sends back a response. All the time, with no relation between the first request and subsequent requests. Also, since it’s request-based, there is no way to send messages from the server to the client without having the client create a request first.

We’ve had a look at how to tackle this problem: using Ajax polling, Long polling an WebSockets. the conclusion was that each of these solutions has it pros and cons. SignalR, an open source project led by some Microsoft developers, is an ASP.NET library which leverages the three techniques described before to create a seamless experience between client and server.

The main idea of SignalR is that the boundary between client and server should become easier to tackle. In this blog post, I will go deeper into how you can use SignalR to achieve real-time communication between client and server over HTTP.

Meet DeckCast

DeckCast is a small sample which I’ve created for this blog post series on SignalR. You can download the source code here: (291.58 kb)

The general idea of DeckCast is that a presenter can navigate to and he can navigate through the slide deck with the arrow keys on his keyboard. One or more clients can then navigate to and view the “presentation”. Note the idea is not to create something you can use to present slide decks over HTTP, instead I’m just showing how to use SignalR to communicate between client and server.

The presenter and viewers will navigate to their URLs:SignalR presentation JavaScript Slide

The presenter will then navigate to a different slide using the arrow keys on his keyboard. All viewers will automatically navigate to the exact same slide at the same time. How much more real-time can it get?

SignalR presentation JavaScript Slide

And just for fun… Wouldn’t it be great if one of these clients was a console application?

SignalR.Client console application

Try doing this today on the web. Chances are you’ll get stuck in a maze of HTML, JavaScript and insanity. We’ll use SignalR to achieve this in a non-complex way, as well as Deck.JS to create nice HTML 5 slides without me having to code too much. Fair deal.

Connections and Hubs

SignalR is built around Connections and Hubs. A Connection is a persistent connection between a client and the server. It represents a communication channel between client and server (and vice-versa, of course). Hubs on the other hand offer an additional abstraction layer and can be used to provide “multicast” connections where multiple clients communicate with the Hub and the Hub can distribute data back to just one specific client or to a group of clients. Or to all, for that matter.

DeckCast would be a perfect example to create a SignalR Hub: clients will connect to the Hub, select the slide deck they want to view and receive slide contents and navigational actions for just that slide deck. The Hub will know which clients are viewing which slide deck and communicate changes and movements to only the intended group of clients.

One additional note: a Connection or a Hub are “transport agnostic”. This means that the SignalR framework will decide which transport is best for each client and server combination. Ajax polling? Long polling? Websockets? A hidden iframe? You don’t have to care about that. The raw connection details are abstracted by SignalR and you get to work with a nice Connection or Hub class. Which we’ll do: let’s create the server side using a Hub.

Creating the server side

First of all: make sure you have NuGet installed and install the SignalR package. Install-Package SignalR will bring down two additional packages: SignalR.Server, the server implementation, and SignalR.Js, the JavaScript libraries for communicating with the server. If your server implementation will not host the JavaScript client as well, installing SignalR.Server will do as well.

We will make use of a SignalR Hub to distribute data between clients and server. A Hub has a type (the class that you create for it), a name (which is, by default, the same as the type) and inherits SignalR’s Hub class. The wireframe for our presentation Hub would look like this:

1 [HubName("presentation")] 2 public class PresentationHub 3 : Hub 4 { 5 }

SignalR’s Hub class will do the heavy lifting for us. It will expose all public methods to any client connecting to the Hub, whether it’s a JavaScript, Console or Silverlight or even Windows Phone client. I see 4 methods for the PresentationHub class: Join, GotoSlide, GotoCurrentSlide and GetDeckContents. The first one serves as the starting point to identify a client is watching a specific slide deck. GotoSlide will be used by the presenter to navigate to slide 0, 1, 2 and so on. GotoCurrentSlide is one used by the viewer to go to the current slide selected by the presenter. GetDeckContents is one which returns the presentation structure to the client: the Title, all slides and their bullets. Let’s translate that to some C#:

1 [HubName("presentation")] 2 public class PresentationHub 3 : Hub 4 { 5 static ConcurrentDictionary<string, int> CurrentSlide { get; set; } 6 7 public void Join(string deckId) 8 { 9 } 10 11 public void GotoSlide(int slideId) 12 { 13 } 14 15 public void GotoCurrentSlide() 16 { 17 } 18 19 public Deck GetDeckContents(string id) 20 { 21 } 22 }

The concurrent dictionary will be used to store which slide is currently being viewed for a specific presentation. All the rest are just standard C# methods. Let’s implement them.

1 [HubName("presentation")] 2 public class PresentationHub 3 : Hub 4 { 5 static ConcurrentDictionary<string, int> DeckLocation { get; set; } 6 7 static PresentationHub() 8 { 9 DeckLocation = new ConcurrentDictionary<string, int>(); 10 } 11 12 public void Join(string deckId) 13 { 14 Caller.DeckId = deckId; 15 16 AddToGroup(deckId); 17 } 18 19 public void GotoSlide(int slideId) 20 { 21 string deckId = Caller.DeckId; 22 DeckLocation.AddOrUpdate(deckId, (k) => slideId, (k, v) => slideId); 23 24 Clients[deckId].showSlide(slideId); 25 } 26 27 public void GotoCurrentSlide() 28 { 29 int slideId = 0; 30 DeckLocation.TryGetValue(Caller.DeckId, out slideId); 31 Caller.showSlide(slideId); 32 } 33 34 public Deck GetDeckContents(string id) 35 { 36 var deckRepository = new DeckRepository(); 37 return deckRepository.GetDeck(id); 38 } 39 }

The code should be pretty straightforward, although there are some things I would like to mention about SignalR Hubs:

  • The Join method does two things: it sets a property on the client calling into this method. That’s right: the server tells the client to set a specific property at the client side. It also adds the client to a group identified by the slide deck id. Reason for this is that we want to group clients based on the slide deck id so that we can broadcast to a group of clients instead of having to broadcast messages to all.
  • The GotoSlide method will be called by the presenter to advance the slide deck. It calls into Clients[deckId]. Remember the grouping we just did? Well, this method returns me the group of clients viewing slide deck deckId. We’re calling the method showSlide n his group. showSlide? That’s a method we will define on the client side! Again, the server is calling the client(s) here.
  • GotoCurrentSlide calls into one client’s showSlide method.
  • GetDeckContents just fetches the Deck from a database and returns the complete object tree to the client.

Let’s continue with the web client side!

Creating the web client side

Assuming you have installed SignalR.JS and that you have already referenced jQuery, add the following two script references to your view:

1 <script type="text/javascript" src="@Url.Content("~/Scripts/jquery.signalR.min.js")"></script> 2 <script type="text/javascript" src="/signalr/hubs"></script>

That first reference is just the SignalR client library. The second reference is a reference to SignalR’s metadata endpoint: it contains information about available Hubs on the server side. The client library will use that metadata to connect to a Hub and maintain the persistent connection between client and server.

The viewer of a presentation will then have to connect to the Hub on the server side. This is probably the easiest piece of code you’ve ever seen (next to Hello World):

1 <script type="text/javascript"> 2 $(function () { 3 // SignalR hub initialization 4 var presentation = $.connection.presentation; 5 $.connection.hub.start(); 6 }); 7 </script>

We’ve just established a connection with the PresentationHub on the server side. We also start the hub connection (one call, even if you are connecting to multiple hubs at once). Of course, the code above will not do a lot. Let’s add some more body.

1 <script type="text/javascript"> 2 $(function () { 3 // SignalR hub initialization 4 var presentation = $.connection.presentation; 5 presentation.showSlide = function (slideId) { 6 $.deck('go', slideId); 7 }; 8 }); 9 </script>

Remember the showSlide method we were calling from the server? This is the one. We’re allowing SignalR to call into the JavaScript method showSlide from the server side. This will call into Deck.JS and advance the presentation. The only thing left to do is tell the server which slide deck we are interested in. We do this immediately after the connection to the hub has been established using a callback function:

1 <script type="text/javascript"> 2 $(function () { 3 // SignalR hub initialization 4 var presentation = $.connection.presentation; 5 presentation.showSlide = function (slideId) { 6 $.deck('go', slideId); 7 }; 8 $.connection.hub.start(function () { 9 // Deck initialization 10 $.extend(true, $.deck.defaults, { 11 keys: { 12 next: 0, 13 previous: 0, 14 goto: 0 15 } 16 }); 17 $.deck('.slide'); 18 19 // Join presentation 20 presentation.join('@Model.DeckId', function () { 21 presentation.gotoCurrentSlide(); 22 }); 23 }); 24 }); 25 </script>

Cool, no? The presenter side of things is very similar, except that it also calls into the server’s GotoSlide method.

Let’s see if we can convert this JavaScript code into come C#as well.  I promised to add a Console application to the mix to show you SignalR is not just about web. It’s also about desktop apps, Silverlight apps and Windows Phone apps. And since it’s open source, I also expect someone to contribute client libraries for Android or iPhone. David, if you are reading this: you have work to do ;-)

Creating the console client side

Install the NuGet package SignalR.Client. This will add the required client library for the console application. If you’re creating a Windows Phone client, SignalR.WP71 will do (Mango).

The first thing to do would be connecting to SignalR’s Hub metadata and creating a proxy for the presentation Hub. Note that I am using the root URL this time (which is enough) and the full type name for the Hub (important!).

1 var connection = new HubConnection("http://localhost:56285/"); 2 var presentationHub = connection.CreateProxy("DeckCast.Hubs.PresentationHub"); 3 dynamic presentation = presentationHub;

Note that I’m also using a dynamic representation of this proxy. It may facilitate the rest of my code later.

Next up: connecting our client to the server. SignalR makes extensive use of the Task Parallel Library (TPL) and there’s no escaping there for you. Start the connection and if something fails, let’s show the client:

1 connection.Start() 2 .ContinueWith(task => 3 { 4 if (task.IsFaulted) 5 { 6 System.Console.ForegroundColor = ConsoleColor.Red; 7 System.Console.WriteLine("There was an error connecting to the DeckCast presentation hub."); 8 } 9 });

Just like with the JavaScript client, we have to join the presentation of our choice. Again, the TPL is used here but I’m explicitly telling it to Wait for the result before continuing my code.

1 presentationHub.Invoke("Join", deckId).Wait();

Because the console does not have any notion about the Deck class and its Slide objects, let’s fetch the slide contents into a dynamic object again. Here’s how:

1 var getDeckContents = presentationHub.Invoke<dynamic>("GetDeckContents", deckId); 2 getDeckContents.Wait(); 3 4 var deck = getDeckContents.Result;

We also want to respond to the showSlide method. Since there’s no means of defining that method on the client in C#in the same fashion as we did it on the JavaScript side, let’s simply use the On method exposed by the hub proxy. It subscribes to a server-side event (such as showSlide) and takes action whenever that occurs. Here’s the code:

1 presentationHub.On<int>("showSlide", slideId => 2 { 3 System.Console.Clear(); 4 System.Console.ForegroundColor = ConsoleColor.White; 5 System.Console.WriteLine(""); 6 System.Console.WriteLine(deck.Slides[slideId].Title); 7 System.Console.WriteLine(""); 8 9 if (deck.Slides[slideId].Bullets != null) 10 { 11 foreach (var bullet in deck.Slides[slideId].Bullets) 12 { 13 System.Console.WriteLine(" * {0}", bullet); 14 System.Console.WriteLine(""); 15 } 16 } 17 18 if (deck.Slides[slideId].Quote != null) 19 { 20 System.Console.WriteLine(" \"{0}\"", deck.Slides[slideId].Quote); 21 } 22 });

We also want to move to the current slide:

1 presentationHub.Invoke("GotoCurrentSlide").Wait();

There we go. The presenter can now switch between slides and all clients, both web and console will be informed and updated accordingly.

SignalR Console Client


SignalR offers a relatively easy to use abstraction over various bidirectional connection paradigms introduced on the web. The fact that its open source and features clients for JavaScript, .NET, Silverlight and Windows Phone in my opinion makes it a viable alternative for applications where you typically use polling or a bidirectional WCF communication channel. Even WCF RIA Services should be a little bit afraid of SignalR as it’s lean and mean!

[edit] There's the Objective-C client:

The sample code for this blog post can be downloaded here: (291.58 kb)

Techniques for real-time client-server communication on the web (SignalR to the rescue)

SignalR websockets html5 long pollingWhen building web applications, you often face the fact that HTTP, the foundation of the web, is a request/response protocol. A client issues a request, a server handles this request and sends back a response. All the time, with no relation between the first request and subsequent requests. Also, since it’s request-based, there is no way to send messages from the server to the client without having the client create a request first.

Today users expect that in their projects, sorry, “experiences”, a form of “real time” is available. Questions like “I want this stock ticker to update whenever the price changes” or “I want to view real-time GPS locations of my vehicles on this map”. Or even better: experiences where people collaborate often require live notifications and changes in the browser so that whenever a user triggers a task or event, the other users collaborating immediately are notified. Think Google Spreadsheets where you can work together. Think Facebook chat. Think Twitter where new messages automatically appear. Think your apps with a sprinkle of real-time sauce.

How would you implement this?

But what if the server wants to communicate with the client?

Over the years, web developers have been very inventive working around the request/response nature of the web. Two techniques are being used on different platforms and provide a relatively easy workaround to the “problem” of HTTP’s paradigm where the client initiates any connection: simple polling using Ajax and a variant of that, long polling.

Simple Ajax polling is, well, simple: the client “polls” the server via an Ajax request the server answers if there is data. The client waits for a while and goes through this process again. Schematically, this would be the following:


A problem with this is that the server still relies on the client initiating the connection. Whenever during the polling interval the server has data for the client, this data can only be sent to the client when the next polling cycle occurs. This is probably no problem when the polling interval is in the 100ms range, apart from the fact that you’ll be hammering your servers when doing that. From the moment your polling interval goes up to say 2 seconds or even 30 seconds, you lose part of the “real time” communication idea.

This problem has been solved by using a technique called “long polling”. The idea is that the client opens an Ajax-based connection to the server, the server does not reply until it has data. The client just has the false feeling that the request is taking a while, and eventually will have some data coming back from the server. Whenever data is returned, the client immediately opens up a “long polling” connection again. Schematically:


There’s no polling interval: as long as the connection is open, the server has the ability to send data back to the client. Awesome, right? Not really… Your servers will not be hammered with billions of requests, but the requests it handles will take a while to complete (the “long poll”). Imagine what your ASP.NET thread pool will do in such case… Well, unless you implement your server-side using an IAsyncHttpHandler or similar. Otherwise, your servers will simply stop accepting requests.

HTML5 to the rescue?

As we’ve seen, both techniques that exist work to simulate full-duplex communication between client and server. However, both of them have some disadvantages if you don’t know what you are doing. Also, the techniques described before are just simulating bi-directional communication. Wouldn’t it be nice to have a solution that works great and was intended to do this? Meet HTML5 WebSockets.

WebSockets offer a real, bi-directional TCP connection between the client and the server. That’s right, a TCP (non-HTTP) connection. To establish a WebSocket connection, the client sends a WebSocket handshake request over HTTP, the server sends a WebSocket handshake response with details on how to open the actual TCP connection. Easy as that! Schematically:


Unfortunately, the web does not evolve that fast… WebSockets are still a draft specification (“CTP” or “alpha” as you will). Not all browsers support them. And because they are using a raw TCP connection, many proxy servers used at companies don’t support them, yet. We’ll get there, just not today. Also, if you want to use WebSockets with ASP.NET, you’ll be forced to use the preview release of .NET 4.5.

So what to do in this messed up world? How to achieve real-time, bi-directional communication over the interwebs, today?

SignalR to the rescue!

SignalR is “an asynchronous signaling library for ASP.NET that Microsoft is working on to help build real-time multi-user web applications”.  Let me rephrase that: SignalR is an ASP.NET library which leverages the three techniques I described before to create a seamless experience between client and server.

The main idea of SignalR is that the boundary between client and server should become easier to tackle. A really quick example would be two parts of code. The client side:

1 var helloConnection = $.connection.hello; 2 3 helloConnection.sayHelloToMe = function (message) { 4 alert(message); 5 }; 6 7 $.connection.hub.start(function() { 8 helloConnection.sayHelloToAll("Hello all!"); 9 });

The server side:

1 public class Hello : Hub { 2 public void SayHelloToAll(string message) { 3 Clients.sayHelloToMe(message); 4 } 5 }

Are you already seeing the link? The JavaScript client calls the C# method “SayHelloToAll” as if it were a JavaScript function. The C# side calls all of its clients (meaning the 200.000 browser windows connecting to this service :-)) JavaScript method “sayHelloToMe” as if it were a C# method.

If I add that not only JavaScript clients are supported but also Windows Phone, Silverlight and plain .NET, does this sound of interest? If I add that SignalR can use any of the three techniques described earlier in this post based on what the client and the server support, without you even having to care… does this sound of interest? If the answer is yes, stay tuned for some follow up posts…