Welcome to William's ekasi

[ Log On ]
2011/10/31
Tags: WP7

UPDATE: SignalR now has a full WP7 client thanks to David Fowl, so most of this post isn’t valid anymore.

I’ve taken quite a keen interest in SignalR lately.  No, I don’t have a specific business need for it but I suspect the more I get used to it the more places I’ll think of using it.  If you don’t know what SignalR is, according to Scott Hanselman it’s “an asynchronous signaling library for ASP.NET” …which doesn’t exactly tell you much.  So my ghetto interpretation is that SignalR is a library that makes it easy for developers to leverage scalable long-running connections between clients and servers.  There’s also some super cool higher level abstractions (called Hubs) which allows you to call Javascript methods from the server side.

Note: I’m not going to look at the Hubs in this post, there’s plenty of information and samples on using hubs available online.

A quick look

SignalRProject

SignalR comes with a sample project which shows how to work with the hubs and a Javascript client – super slick!  To create a SignalR application you need a client and a server.  We’ll start with the server which we’ll host inside a MVC app.

The server

Use NuGet to add a reference to SignalR.Server.

Create a new class that represents your server logic and extend from PersistentConnection and override the OnReivedAsync method.  This method will be called whenever a client sends data to the server.

DemoConnection

In the example I’m received a JSon result representing a PriceUpdateData object.  Once I’ve deserialized the JSon I can do whatever I want with the data.

The next step is to tell SignalR to expose this connection for clients to consume.  We do this using routes.

Add a MapConnection route in your global.asax RegisterRoutes method (make sure to include SignalR.Routing in your using statements for the MapConnection extension method).

Routes

This will add a route to the routing engine so that whenever a request comes in for Server/pricing your DemoConnection class will handle it.

The Client

The client in this case is a WP7 device.  As it stands now, there is no native WP7 client available for SignalR.  Thankfully it’s not a big deal to make one work… unless you want to work with hubs – which is why I’m not touching them in this post.  The SignalR.Client project can’t be added as a reference to a WP7 app since it’s not a silverlight assembly.  Which means creating one.

But let’s first take a look at the original SignalR.Client project.

SignalR.Client

Ignoring the hubs there’s not too much work to do in order to get this to work on a WP7 device.  My first thought was just to new up a new WP7 assembly project and copy-pasta everything in.  Which works pretty well except there are a few gotchas:

  • The TPL isn’t available by default in WP7 (there’s a NuGet package available to fill that gap though)
  • WP7 doesn’t support Tracing, so all tracing commands need to be removed
  • HttpWebRequest on WP7 doesn’t support the ContentLength property
  • HttpWebRequests need to be closed before you can get access to the HttpWebResponse
  • WP7 doesn’t support System.Dynamic

None of those are dealbreakers except for System.Dynamic, but only in the case of Hubs.  Hubs currently make use of DynamicObject which means the copy-pasta route won’t work at all there… which is why I’m leaving it out for now :)

File –> New Project

I created a new SignalR.Client.WP7 project, and copied the required files form the original project.  Next we need to fix the WP7 specific issues:

Add the System.Threading.Tasks NuGet package for TPL support.

Wrap the Trace calls inside compiler directives (inside TaskAsyncHelper.cs):

Trace

Wrap the request.ContentLength = buffer.LongLength inside compiler directives (HttpHelper.cs).  While here, also close the Request Stream before trying to access the ResponseStream:

Length

Using the client

Now that we have a WP7 assembly we can use it in our apps.

Phone

And that’s it. We now have communication between the phone and a server using SignalR.

You can download my SignalR.Client.WP7 project here.  I’ve also submitted a pull-request to get it added to the main project so it might be appearing as part of a NuGet package soon.

UPDATE: SignalR now has a full WP7 client thanks to David Fowl, so most of this post isn’t valid anymore.