Logo

Maarten Balliauw {blog}

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

About the author

Maarten Balliauw is currently employed as a Technical Evangelist at JetBrains. His interests are mainly web applications developed in ASP.NET (C#) or PHP and the Windows Azure cloud platform.
More about me More about me
Send mail E-mail me


ASP.NET MVC Quickly Pro NuGet Subscribe to my RSS feed Follow me on Twitter! View Maarten Balliauw's profile on LinkedIn
Maarten Balliauw - MVP - Most Valuable Professional
Maarten Balliauw - ASPInsider

Search

Archive

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright Maarten Balliauw 2013


SymbolSource support for NuGet Package Source Discovery

A couple of weeks, I told you about NuGet Package Source Discovery. In short, it allows you to add some meta information to your website and use your website as a discovery document for NuGet feeds. And thanks to a contribution to the spec by Marcin from SymbolSource.org, Package Source Discovery (PSD) now supports configuring Visual Studio for consuming symbols as well. Nifty!

An example

Let’s go with an example. If we discover packages from my blog, some feeds will be added to NuGet in Visual Studio.

1 Install-Package DiscoverPackageSources 2 Discover-PackageSources -Url "http://blog.maartenballiauw.be"

Because my blog links to my feeds on MyGet, I can provide my MyGet credentials with it:

1 Install-Package DiscoverPackageSources 2 Discover-PackageSources -Url "http://blog.maartenballiauw.be" -Username maarten -Password s3cr3t

Note I’ve stripped out some of the secrets in the examples but I’m sure you get the idea.

What’s interesting is that because I provided credentials, MyGet also returned the SymbolSource URL for my feeds and it registered them automatically in Visual Studio.

Symbol server

Now that’s what I call being lazy in a professional manner!

On a side note… NuGet Feed Discovery

While not completely related to SymbolSource support, it’s worth mentioning that Package Source Discovery also got support for that other NuGet discovery protocol by the guys at Inedo, NuGet Feed Discovery (NFD). NFD differs from PSD in that both specs have a different intent.

  • NFD is a convention-based API endpoint for listing feeds on a server
  • PSD is a means of discovering feeds from any URL given

The fun thing is: if you add an NFD url to your web site’s metadata, it will also be added into Visual Studio by using NuGet Package Source Discovery. For reference, here’s an example where I add my local NuGet feeds to my blog for discovery:

1 <link rel="nuget" 2 type="application/atom+xml" 3 title="Local feeds" 4 href="http://localhost:8888/nugetext/discover-feeds" />

Enjoy!


Categories: ASP.NET | C# | General | ICT | NuGet

NuGet Package Source Discovery

It’s already been 2 years since NuGet was introduced. This.NET package manager features the concept of feeds, or “package sources”, on which packages containing .NET libraries and tools can be hosted. In fact, support for feeds inspired us to build www.myget.org. While not all people are aware of this, Microsoft started out with two feeds as well: one for www.nuget.org, the other one for the Orchard CMS.

More and more feeds are being created daily, both by Microsoft as well as others. Here’s a list of feeds Microsoft has that I know of (there are probably more):

Wouldn’t it be nice if we could add them all to our Visual Studio package sources without having to know these URL’s? Meet the NuGet Package Source Discovery specification, or in short: PSD, a specification Xavier, Scott, PhilJeff, Howard and myself have been working on (thanks guys!)

Package Source Discovery

Because PowerShell says more than words, try the following. Open Visual Studio and open any solution. Then issue the following in the Package Manager Console:

1 Install-Package DiscoverPackageSources 2 Discover-PackageSources -Url "http://blog.maartenballiauw.be"

While we’re at it, perhaps the Glimpse project has something to discover as well.

1 Discover-PackageSources -Url "http://getglimpse.com"

Close and re-open Visual Studio and check your package sources. Notice anything new? My blog has provided you with 2 feeds. And you’ve also been subscribed to Glimpse’s nightly builds feed.

But there’s more. If you would have been authenticated when connecting to my blog, it will yield API keys as well. This allows the PSD client to setup everything that is needed for me to work with my personal feeds, both consuming and producing, by just remembering the URL of my blog.

Package Source Discovery boils down to trust. Since you apparently trust me, you can discover feeds from my blog. If you trust Microsoft, discover feeds from www.microsoft.com. Do you trust Windows Azure? Get their packages by discovering feeds at www.windowsazure.com. Need your company feeds? Discover them at http://nuget. A lot of options and possibilities there!

Recycling standards

If you are a blogger and are using Windows Live Writer, you’ve already used this before. We’ve written the NuGet Package Source Discovery specification based on what happens with blogs: when a simple <link /> element is added to your HTML, you are compatible with feed discovery. Here are the two elements that are listed in the source code for my blog:

1 <link rel="nuget" type="application/atom+xml" title="Maarten Balliauw NuGet feed" href="http://www.myget.org/F/maartenballiauw" /> 2 <link rel="nuget" type="application/rsd+xml" href="http://www.myget.org/Discovery/Feed/googleanalyticstracker" />

The first one points directly to a feed. Using the URL and the title attribute, we can add this one to our NuGet package sources with ease. The second one points to an RSD file, known since ages as the Really Simple Discovery format described on https://github.com/danielberlinger/rsd. We’ve recycled it to allow a lot of things at the client side. Since not all required metadata can be obtained from the RSD format, the Dublin Core schema is present in the PSD response as well.

Here’s an an example:

1 <?xml version="1.0" encoding="utf-8"?> 2 <rsd version="1.0" xmlns:dc="http://purl.org/dc/elements/1.1/"> 3 <service> 4 <engineName>MyGet</engineName> 5 <engineLink>http://www.myget.org</engineLink> 6 7 <dc:identifier>http://www.myget.org/F/googleanalyticstracker</dc:identifier> 8 <dc:creator>maartenba</dc:creator> 9 <dc:owner>maartenba</dc:owner> 10 <dc:title>Staging feed for GoogleAnalyticsTracker</dc:title> 11 <dc:description>Staging feed for GoogleAnalyticsTracker</dc:description> 12 <homePageLink>http://www.myget.org/gallery/googleanalyticstracker</homePageLink> 13 14 <apis> 15 <api name="nuget-v2-packages" preferred="true" apiLink="http://www.myget.org/F/googleanalyticstracker/api/v2" blogID="" /> 16 <api name="nuget-v2-push" preferred="true" apiLink="http://www.myget.org/F/googleanalyticstracker/api/v2/package" blogID=""> 17 <settings> 18 <setting name="apiKey">abcdefghijkl</setting> 19 </settings> 20 </api> 21 <api name="nuget-v1-packages" preferred="false" apiLink="http://www.myget.org/F/googleanalyticstracker/api/v1" blogID="" /> 22 </apis> 23 </service> 24 </rsd> 25

As you can see, using RSD we can embed a lot more information about a feed in this document. If we wanted to add a link to someone’s GitHub and have a client that wants to use this, we can add another <api /> element in here.

Who is using this?

I am (http://blog.maartenballiauw.be), Xavier is (http://www.xavierdecoster.com), Glimpse is (http://getglimpse.com), NancyFX is (http://www.nancyfx.org) and MyGet has implemented several endpoints as well. Why don't you join the wonderful world of package source discovery?

Feedback needed!

This is not part of NuGet out of the box yet. We need your feedback, comments, implementations and so on. Head over to our GitHub repository, read through the spec and all examples and provide us with your thoughts. Try the two clients we’ve crafted (more on Xavier's blog) and make your NuGet repositories discoverable. Feel free to post a link to your blog below.

Enjoy and let the commenting begin!


Categories: ASP.NET | C# | General | ICT | NuGet | Personal | Projects | Software

Working with Windows Azure command line tools from within Visual Studio

Right after my last post (Working with Windows Azure command line tools from PhpStorm), the obvious question came to mind… Can I do Windows Azure things using the command line tools from within Visual Studio as well? Sure you can! At least if you have the NuGet Package Manager Console installed into your Visual Studio.

For good order: you can use either the PowerShell cmdlets that are available or use the Node-based tools available (how-to). In this post we’ll be using the PowerShell cmdlets. And once those are installed… there’s nothing you have to do to get these working in Visual Studio!

The first thing we’ll have to do before being able to do anything with these cmdlets is making sure we can access the Windows Azure management service. Invoke the Get-AzurePublishSettings command. This will open op a new browser window and generate a .publishsettings. Save it somewhere and remember the full path to it. Next, we’ll have to import that file using the Import-AzurePublishSettingsFile <path to publishsettings file> command.

If everything went according to plan, we’ll now be able to do some really interesting things from inside our NuGet Package Manager console. Let’s see if we can list all Windows Azure Web Sites under our subscription… Get-AzureWebsite should do!

List Windows Azure Web Site from NuGet Package Manager console

And it did. Let’s scale our brewbuddy website and make use of 3 workers.

image

Whoa!

For reference, here’s the full list of supported cmdlets. There’s also Glenn Block’s post on some common recipes you can mash together using these cmdlets. Enjoy!

[edit] Sandrino Di Mattia has a take on this as well: http://fabriccontroller.net/blog/posts/using-the-windows-azure-cli-on-windows-and-from-within-visual-studio/


MyGet Build Services - Join the private beta!

Good news! Over the past 4 weeks we’ve been sending out tweets about our secret project MyGet project “wonka”. Today is the day Wonka shows his great stuff to the world… In short: MyGet Build Services enable you to add packages to your feed by just giving us your GitHub repo. We build it, we package it, we publish it.

Our build server searches for a file called MyGet.sln and builds that. No probem if it's not there: we'll try and build other projects then. We'll run unit tests (NUnit, XUnit, MSTest and some more) and fail when those fail. We'll search for packages generated by your solution and if none are generated, we take a wild guess and create them for you.

To make it more visual, here are some screenshots. First, you have to add a build source, for example a GitHub repository (in fact, GitHub is all we currently support):

MyGet Add build source

After that, you simply click “Build”. A couple of seconds or minutes later, your fresh package is available on your feed:

MyGet build package

MyGet package result

If you want to see what happened, the build log is available for review as well:

MyGet build log

Enroll now!

Starting today, you can enroll for our private beta. You’ll get on a waiting list and as we improve build capacity, you will be granted access to the beta. If you’re in, tell us how it behaves. What works, what doesn’t, what would you like to see improved. Enroll for this private beta now via http://www.myget.org/buildservices. Limited seats!

Do note it’s still a beta, and as Willy Wonka would say… “Little surprises around every corner, but nothing dangerous.”

Happy packaging!


Categories: C# | General | ICT | NuGet | Projects | Testing

Use NuGet Package Restore to avoid pushing assemblies to Windows Azure Websites

Windows Azure Websites allows you to publish a web site in ASP.NET, PHP, Node, … to Windows Azure by simply pushing your source code to a TFS or Git repository. But how does Windows Azure Websites manage dependencies? Do you have to check-in your assemblies and NuGet packages into source control? How about no…

NuGet 1.6 shipped with a great feature called NuGet Package Restore. This feature lets you use NuGet packages without adding them to your source code repository. When your solution is built by Visual Studio (or MSBuild, which is used in Windows Azure Websites), a build target calls nuget.exe to make sure any missing packages are automatically fetched and installed before the code is compiled. This helps you keep your source repo small by keeping large packages out of version control.

Enabling NuGet Package Restore

Enabling NuGet package restore can be done from within Visual Studio. Simply right-click your solution and click the “Enable NuGet Package Restore” menu item.

NuGet package restore Windows Azure Websites Antares

Visual Studio will now do the following with the projects in your solution:

  • Create a .nuget folder at the root of your solution, containing a NuGet.exe and a NuGet build target
  • Import this NuGet target into all your projects so that MSBuild can find, download and install NuGet packages on-the-fly when creating a build

Be sure to push the files in the .nuget folder to your source control system. The packages folder is not needed, except for the repositories.config file that sits in there.

But what about my non-public assembly references? What if I don't trust auto-updating from NuGet.org?

Good question. What about them? A simple answer would be to create NuGet packages for them. And if you already have NuGet packages for them, things get even easier. Make sure that you are hosting these packages in an online feed which is not the public NuGet repository at www.nuget.org, unless you want your custom assemblies out there in public. A good choice would be to checkout www.myget.org and host your packages there.

But then a new question surfaces: how do I link a custom feed to my projects? The answer is pretty simple: in the .nuget folder, edit the NuGet.targets file. In the PackageSources element, you can supply a semicolon (;) separated list of feeds to check for packages:

1 <?xml version="1.0" encoding="utf-8"?> 2 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 3 <PropertyGroup> 4 <!-- ... --> 5 6 <!-- Package sources used to restore packages. By default will used the registered sources under %APPDATA%\NuGet\NuGet.Config --> 7 <PackageSources>"http://www.myget.org/F/chucknorris;http://www.nuget.org/api/v2"</PackageSources> 8 9 <!-- ... --> 10 </PropertyGroup> 11 12 <!-- ... --> 13 </Project>

By doing this and pushing the targets file to your Windows Azure Websites Git or TFS repo, the build system backing Windows Azure Websites will go ahead and download your packages from an external location, not cluttering your sources. Which makes for one, happy cloud.

Windows Azure Git Deploy


Pro NuGet is finally there!

Short version: Install-Package ProNuget or http://amzn.to/pronuget

Pro NuGet - Continuous integration Package RestoreIt’s been a while since I wrote my first book. After I’ve been telling that writing a book is horrendous (try writing a chapter per week after your office hours…) and that I would never write on again, my partner-in-crime Xavier Decoster and I had the same idea at the same time: what about a book on NuGet? So here it is: Pro NuGet is fresh off the presses (or on Kindle).

Special thanks go out to Scott Hanselman and Phil Haack for writing our foreword. Also big kudos to all who’ve helped us out now and then and did some small reviews. Yes Rob, Paul, David, Phil, Hadi: that’s you guys.

Why a book on NuGet?

Why not? At the time we decided we would start writing a book (september 2011), NuGet was out there for a while already. Yet, most users then (and still today) were using NuGet only as a means of installing packages, some creating packages. But NuGet is much more! And that’s what we wanted to write about. We did not want to create a reference guide on what NuGet command were available. We wanted to focus on best practices we’ve learned over the past few months using NuGet.

Some scenarios covered in our book:

  • What’s the big picture on package management?
  • Flashback last week: NuGet.org was down. How do you keep your team working if you depend on that external resource?
  • Is it a good idea to auto-update NuGet packages in a continous integration process?
  • Use the PowerShell console in VS2010/11. How do I write my own NuGet PowerShell Cmdlets? What can I do in there?
  • Why would you host your own NuGet repository?
  • Using NuGet for continuous delivery
  • More!

I feel we’ve managed to cover a lot of concepts that go beyond “how to use NuGet vX” and instead have given as much guidance as possible. Questions, suggestions, remarks, … are all welcome. And a click on “Add to cart” is also a good idea ;-)


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 2012.zip (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.


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 Apigee.com 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", "www.example.org"); 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", "www.example.org"); 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", "www.example.org"); 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", "www.example.org")] 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", "www.example.org", 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!


Categories: ASP.NET | C# | General | ICT | Logging | NuGet | Projects | Software

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: DeckCast.zip (291.58 kb)

The general idea of DeckCast is that a presenter can navigate to http://example.org/Deck/Present/SomeDeck and he can navigate through the slide deck with the arrow keys on his keyboard. One or more clients can then navigate to http://example.org/Deck/View/SomeDeck 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

Conclusion

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: https://github.com/DyKnow/SignalR-ObjC

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


Publishing symbol packages for a MyGet feed

MyGet host your NuGet feed serverEver since NuGet 1.2, there is a great way for NuGet package authors to let their users debug into the package’s binaries. With almost no additional effort, package authors can publish their symbols and sources, and package consumers can debug into them from Visual Studio, simply by pushing a symbols package in addition to the standard NuGet package.

SymbolSourceToday, we’re proud to announce MyGet has partnered with SymbolSource.org to offer an easy workflow to publish symbol packages for a private MyGet feed. This means from now on you can publish symbol packages for your private feeds as well!

On a sidenote: we're sharing API keys between both services. If you also want to share the same password with both services, simply go to your MyGet profile page and re-enter your password. We'll keep it in sync after that.

Publishing a symbols package for use with MyGet

As I will assume you are used to publishing packages to NuGet and SymbolSource, here’s what changes. First of all, you will require the URLs to which to publish. Log in to MyGet and browse to your feed details. The Feed Details tab will give you all the information you need, as you can see in the following screenshot:

image

In short, your feed URL remains the same. If you want to consume your private feed in Visual Studio or using the NuGet Package Manager Console, simply add http://www.myget.org/F/yourfeedname as the source. The thing that changed is the publish URL: if you want to publish your packages to MyGet, use the URL http://www.myget.org/F/yourfeedname/api/v1 as the publish URL. For symbol packages, your URL will be in the form of http://nuget.gw.symbolsource.org/MyGet/yourfeedname.

The publish workflow to publish the SamplePackage.1.0.0.nupkg to a MyGet feed, including symbols, would be issuing the following two commands from the console:

1 nuget push SamplePackage.1.0.0.nupkg 00000000-0000-0000-0000-00000000000 -Source http://www.myget.org/F/somefeed/api/v1 2 3 nuget push SamplePackage.1.0.0.Symbols.nupkg 00000000-0000-0000-0000-00000000000 -Source http://nuget.gw.symbolsource.org/MyGet/somefeed

An example of these commands can also be found on the Feed Details tab for your MyGet feed.

Consuming symbol packages in Visual Studio

When logging in to MyGet, you can find the symbols URL compatible with Visual Studio under the Feed Details tab for your MyGet feed. This URL will be the same for all feeds you are allowed to consume, so no need to configure 10+ symbol servers in Visual Studio. Here’s how to configure it.

First of all, Visual Studio typically will only debug your own source code, the source code of the project or projects that are currently opened in Visual Studio. To disable this behavior and to instruct Visual Studio to also try to debug code other than the projects that are currently opened, open the Options dialog (under the menu Tools > Options). Find the Debugging node on the left and click the General node underneath. Turn off the option Enable Just My Code. Also turn on the option Enable source server support. This usually triggers a warning message but it is safe to just click Yes and continue with the settings specified.

MyGet symbol server in Visual Studio

Keep the Options dialog opened and find the Symbols node under the Debugging node on the left. In the dialog shown in Figure 4-14, add the symbol server URL for your MyGet feed: http://srv.symbolsource.org/pdb/MyGet/username/11111111-1111-1111-1111-11111111111. After that, click OK to confirm configuration changes and consume symbols for NuGet packages.

Enjoy!