Maarten Balliauw {blog}

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

NAVIGATION - SEARCH

Developing for the Tessel with WebStorm

image_thumb[1]In a previous post, I mentioned that (finally) my Tessel arrived, “an internet-connected microcontroller programmable in JavaScript”. I like WebStorm a lot as an IDE, and since the Tessel runs on JavaScript code (via node), why not see if WebStorm can be more than just an editor for Tessel development…

Developing JavaScript

The Tessel runs JavaScript, so naturally a JavaScript IDE like WebStorm will be splendid at that part. It provides a project system, code completion, navigation, inspections to check whether my code is as it should be (which from the screenshot below, it is not, yet ;-)) and so on.

WebStorm Tessel Node JavaScript

What I like a lot is that everything related to the device-side of my project (a thermometer thing that posts data to the Internet), is in one place. The project system ensures the IDE can be intelligent about code completion and navigation, I can see the npm modules I have installed, I can use version control and directly push my changes back to a GitHub repository. The Terminal tool window lets me run the Tessel command line to run scripts and so on. No fiddling with additional tools so far!

Tessel Command Line Tools

As I explained in a previous blog post, the Tessel comes with a command line that is used toconnect the thing to WiFi, run and deploy scripts and read logs off it (and more). I admit it: I am bad at command line things. After a long time, commands get engraved in my memory and I’m quite fast at using them, but new command line tools, like Tessel’s, are something that I always struggle with at the start.

To help me learn, I thought I’d add the Tessel command line to WebStorm’s Command Line Tools. Through the Project Settings | Command Line Tool Support,, I added the path to Tessel’s tool (%APPDATA%\npm\tessel.cmd). Note that you may have to install the Command Line Tools Plugin into WebStorm, I’m unsure if it’s bundled.

Tessel Command Line 

This helps in getting the Tessel commands available in the Command Line Tools after pressign Ctrl+Shift+X (or Tools | Run Command…), but it still does not help me in learning this new command’s syntax, right? Copy this gist into C:\Users\<your username>\.WebStorm8\config\commandlinetools\Custom_tessel.xml and behold: completion for these commands!

Tessel command line auto completion

Again, I consider them as training wheels until I start memorizing the commands. I can remember tessel run, but it’s all the one’s that I’m not using cntinuously that I tend to forget…

Running Code on the Tessel

Running code on the Tessel can be done using the tessel run <script.js> command. However, I dislike having to always jump into a console or even the command line tools mentioned earlier to just run and see if things work. WebStorm has the concept of Run/Debug Configurations, where using a simple keystroke (Shift+F10) I can run the active configuration without having to switch my brain context to a console.

I created two configurations: one that runs nodejs on my own computer so I can test some things, and one that invokes tessel run. Provide the path to node, set the working directory to the current project folder, specify the Tessel command line script as the file to execute and provide run somescript.js as the parameters.

Tessel Run

Quick note here: after a few massive errors coming from Tessel’s command line tool that mentioned the device only supports one connection, it’s bes tto check the Single instance only box for the run configuration. This ensures the process is killed and restarted whenever the script is ran.

Save, Shift+F10 and we’re deploying and running whenever we want to test our code.

Run code on Tessel from WebStorm

Debugging does not work, as the Tessel does not support this. I hope support for it will be added, ideally using the V8 debugger so WebStorm can hook into it, too. Currently I’m doing “poor man’s debugging”: dumping variables using console.log() mostly…

External Tools

When I first added Tessel to WebStorm, I figured it would be nice to have some menu entries to invoke commands like updating the firmware (a weekly task,Tessel is being actively developed it seems!) or showing the device’s WiFi status. So I did!

Tessel External Tools

External Tools can be added under the IDE Settings | External Tools and added to groups and so on. Here’s what I entered for the “Update firmware” command:

Update Tessel from WebStorm

It’s basically just running node, passing it the path to the Tessel command line script and appending the correct parameter.

Now, I don’t use my newly created menu too much I must say. Using the command line tools directly is more straightforward. But adding these external tools does give an additional advantage: since I have to re-connect to the WiFi every now and then (Tessel’s WiFi chip is a bit flakey when further away from the access point), I added an external tool for connectingit to WiFi and assigned a shortcut to it (IDE Settings | Keymaps, search for whatever label you gave the command and use the context menu to assign a keyboard shortcut). On my machine, Ctrl+Alt+W resets the Tessel’s WiFi now!

Installing npm Packages

This one may be overkill, but I found searching npm for Tessel-related packages quite handy through the IDE. From Project Settings | Node.JS and NPM, searching packages is pretty simple. And installing them, too! Careful, Tessel’s 32 MB of storage may not like too many modules…

NPM webstorm

Fun fact: writing this blog post, I noticed the grunt-tessel package which contains tasks that run or deploy scripts to the device. If you prefer using Grunt for doing that, know WebStorm comes with a Grunt runner, too.

That’s it, for now, I do hope to tinker away on the Tessel in the next weeks nad finish my thermometer and the app so I can see the (historical) temperature in my house,

Getting Started with the Tessel

Tessel LogoSomewhere last year (I honestly no longer remember when), I saw a few tweets that piqued my interest: a crowdfunding project for the Tessel, “an internet-connected microcontroller programmable in JavaScript”. Since everyone was doing Arduino and Netduino and JavaScript is not the worst language ever, I thought: let’s give these guys a bit of money! A few months later, they reached their goal and it seemed Tessel was going to production. Technical Machine, the company behind the device, sent status e-mails on their production process every couple of weeks and eventually after some delays, there it was!

Plug, install (a little), play!

After unpacking the Tessel, I was happy to see it was delivered witha micro-USB cable to power it, a couple of stuickers and the climate module I ordered with it (a temperature and humidity sensor). The one-line manual said “http://tessel.io/start”, so that’s where I went.

The setup is pretty easy: plug it in a USB port so that Windows installs the drivers, install the tessel package using NPM and update the device to the latest firmware.

npm install -g tessel tessel update

Very straightforward! Next, connecting it to my WiFi:

tessel wifi -n <ssid> -p <password> -s wpa2 -t 120

And as a test, I managed to deploy “blinky”, a simple script that blinks the leds on the Tessel.

tessel blinky

Now how do I develop for this thing…

My first script (with the climate module)

One of the very cool things about Tessel is that all additional modules have something printed on them… The climate module, for example, has the text “climate-si7005” printed on it.

climate-si7005

Now what does that mean? Well, it’s also the name of the npm package to install to work with it! In a new directory, I can now simply initialzie my project and install theclimate module dependency.

npm init npm install climate-si7005

All modules have their npm package name printed on them so finding the correct package to work with the Tessel module is quite easy. All it takes is the ability to read. The next thing to do is write some code that can be deployed to the Tessel. Here goes:

The above code uses the climate module and prints the current temperature (in Celsius, metric system for the win!) on the console every second. Here’s a sample, climate.js.

var tessel = require('tessel'); var climatelib = require('climate-si7005'); var climate = climatelib.use(tessel.port['A']); climate.on('ready', function () { setImmediate(function loop () { climate.readTemperature('c', function (err, temp) { console.log('Degrees:', temp.toFixed(4) + 'C'); setTimeout(loop, 1000); }); }); });

The Tessel takes two commands that run a script: tessel run climate.js, which will copy the script and node modules onto the Tessel and runs it, and tessel push climate.js which does the same but deploys the script as the startup script so that whenever the Tessel is powered, this script will run.

Here’s what happens when climate.js is run:

tessel run climate.js

The output of the console.log() statement is there. And yes, it’s summer in Belgium!

What’s next?

When I purchased the Tessel, I had the idea of building a thermometer that I can read from my smartphone, complete with history, min/max temperatures and all that. I’ve been coding on it on and off in the past weeks (not there yet). Since I’m a heavy user of PhpStorm and WebStorm for doing non-.NET development, I thought: why not also see what those IDE’s can do for me in terms of developing for the Tessel… I’ll tell you in a next blog post!

Visual Studio Online for Windows Azure Web Sites

Today’s official Visual Studio 2013 launch provides some interesting novelties, especially for Windows Azure Web Sites. There is now the choice of choosing which pipeline to run in (classic or integrated), we can define separate applications in subfolders of our web site, debug a web site right from within Visual Studio. But the most impressive one is this. How about… an in-browser editor for your application?

Editing Node.JS in browser

Let’s take a quick tour of it. After creating a web site we can go to the web site’s configuration we can enable the Visual Studio Online preview.

Edit in Visual Studio Online

Once enabled, simply navigate to https://<yoursitename>.scm.azurewebsites.net/dev or click the link from the dashboard, provide your site credentials and be greeted with Visual Studio Online.

On the left-hand menu, we can select the feature to work with. Explore does as it says: it gives you the possibility to explore the files in your site, open them, save them, delete them and so on. We can enable Git integration, search for files and classes and so on. When working in the editor we get features like autocompletion, FInd References, Peek Definition and so on. Apparently these don’t work for all languages yet, currently JavaScript and node.js seem to work, C# and PHP come with syntax highlighting but nothing more than that.

Peek definition

Most actions in the editor come with keyboard shortcuts, for example Ctrl+, opens navigation towards files in our application.

Navigation

The console comes with things like npm and autocompletion on most commands as well.

Console in Visual Studio Online

I can see myself using this for some scenarios like on-the-road editing from a Git repository (yes, you can clone any repo you want in this tool) or make live modifications to some simple sites I have running. What would you use this for?

Developing Windows Azure Mobile Services server-side

Word of warning: This is a partial cross-post from the JetBrains WebStorm blog. The post you are currently reading adds some more information around Windows Azure Mobile Services and builds on a full example and is a bit more in-depth.

With Microsoft’s Windows Azure Mobile Services, we can build a back-end for iOS, Android, HTML, Windows Phone and Windows 8 apps that supports storing data, authentication, push notifications across all platforms and more. There are client libraries available for all these platforms which can be used when developing in an IDE of choice, e.g. AppCode, Google Android Studio or Visual Studio. In this post, let’s focus on what these different platforms have in common: the server-side code.

This post was sparked by my buddy Kristof Rennen’s session for our user group. During his session he mentioned a couple of times how he dislikes Node.js and the trial-and-error manner of building the server-side due to lack of good tooling. Working for a tooling vendor and intrigued by the quest of finding a better way, I decided to post the short article you are currently reading.

Do note that I will focus more on how to get your development environment set-up and less on the Windows Azure Mobile Services feature set. Yes, you will learn some of the very basics but there are way better resources available for getting in-depth knowledge on the topic.

Here’s what we will see in this post:

  • Setting up a Windows Azure Mobile Service
  • Creating a table and storing data
  • A simple HTML/JS client
  • Adding logic to our API
  • Working on server-side logic with WebStorm
  • Sending e-mail using an Node.js module
  • Putting our API to the test with the REST client
  • Unit testing our logic

The scenario

Doing some exploration is always more fun when we can do it based on a simple scenario. Whenever JetBrains goes to a conference and we have a booth, we like to do a raffle for licenses. The idea is simple: come to our booth for a chat, fill out a simple form and we will pick random names after the conference and send a free license.

For this post, I’ve created a very simple form in HTML and JavaScript, collecting visitor name and e-mail address.

1

Once someone participates in the raffle, the name and e-mail address are stored in a database and we send out an e-mail thanking that person for visiting the booth together with a link to download a product trial.

Setting up a Windows Azure Mobile Service

First things first: we will require a Windows Azure account to start developing. Next, we can create a new Mobile Service through the Windows Azure Management Portal.

2

Next, we can give our service a name and pick the datacenter location for it. We also have to provide the type of database we want to use: a free, 20 MB database, or a full-fledged SQL Database. While Windows Azure Mobile Services is always coupled to a database, we can build a custom API with it as well.

3

Once completed, we get several tabs to work with. There’s the initial welcome screen, displaying links to documentation and client libraries. The other tabs give access to monitoring, scaling, how we want to authenticate users, push notification settings and logs. Since we want to store data of booth visitors, let’s enter the Data tab.

Creating a table and storing data

From the Data tab, we can create a new table. Let’s call it Visitor. When creating a new table, we have to specify access rules for the API that will be available on top of it.

4

We can tell who can read (API GET request), insert (API POST request), update (API PATCH request) and delete (API DELETE request). Since our application will only insert new data and we don’t want to force booth visitors to log in with their social profiles, we can specify inserts can be done if an API key is provided. All other operations will be blocked for outside users: reading and deleting will only be available through the Windows Azure Management Portal with the above settings.

Do we have to create columns for storing booth visitor data? By default, Windows Azure Mobile Services has “dynamic schema” enabled which means we can throw some JSON at our Mobile Service it and it will store data for us.

A simple HTML/JS client

As promised earlier in this post, let’s see how we can build a simple client for the service we have just created. We’ll go with an HTML and JavaScript based client as it’s fairly easy to demonstrate. Again, have a look at other client SDK’s for the platform you are developing for.

Our HTML page exists of nothing but two text boxes and a button, conveniently named name, email and send. There are two ways of sending data to our Mobile Service: calling the API directly or making use of the client library provided. Both are easy to do: the API lives at https://<servicename>.azure-mobile.net/tables/<tablename> and we can POST a JSON-serialized object to it, an approach we’ll take later in this blog post. There is also a JavaScript client library available from https://<servicename>.azure-mobile.net/client/MobileServices.Web-1.0.0.min.js which our client is using.

5

As we can see, a new MobileServiceClient is created on which we can get a table reference (getTable) and insert a JSON-formatted object. Do note that we have to pass in an API key in the client constructor, which can be obtained from the Windows Azure Management Portal under the Manage Keys toolbar button.

From the portal, we can now see the data we’re submitting from our simple application:

6

Adding logic to our API

Let’s make it a bit more exciting! What if we wanted to store a timestamp with every record? We may want to have some insight into when our booth was busiest. We can send a timestamp from the client but that would only add clutter to our client-side code. Also if we wanted to port the HTML/JS client to other platforms it would mean we have to make sure every client sends this data to our mobile service. In short: this calls for some server-side logic.

For every table created, we can make use of the Script tab to add custom logic to read, insert, update and delete operations which we can write in JavaScript. By default, this is what a script for insert may look like:

7

The insert function will be called with 3 parameters: the item to be stored (our JSON-serialized object), the current user and the full request. By default, the request.execute() function is called which will make use of the other two parameters internally. Let’s enrich our item with a timestamp.

8

Hitting Save will deploy this script to our mobile service which from now on will store an inserted timestamp in our database as well.

This is a very trivial example. There are a lot of things that can be done server-side: enforcing validation, record filtering, storing data in other tables as well, sending e-mail or text messages, … Here’s a post with some common scenarios. Full reference to the server-side objects is also available.

Working on server-side logic with WebStorm

Unfortunately, the in-browser editor for server-side scripts is a bit limited. It features no autocompletion and all code has to go in one file. How would we create shared logic which can be re-used across different scripts? How would we unit test our code? This is where WebStorm comes in. We can access the complete server-side code through a Git repository and work on it in a full IDE!

The Git access to our mobile service is disabled by default. Through the portal’s right-hand side menu, we can enable it by clicking the Set up source control link. Next, we can find repository details from the Configure tab.

9

We can now use WebStorm’s VCS | Checkout From Version Control | Git menu to bring down the server-side code for our Windows Azure Mobile Service.

10

In our project, we can see several folders and files. The service/api folder can hold custom API’s (check the readme.md file for more info). service/scheduler can hold scripts that execute at a given time or interval, much like CRON jobs. service/shared can hold shared scripts that can be used inside table logic, custom API’s and scheduler scripts. In the service/table folder we can find the script we have created through the portal: visitor.insert.js. Also note the visitor.json file which contains the access rules we configured through the portal earlier.

11

From now on, we can work inside WebStorm and push to the remote Git repository if we want to deploy our new code.

Sending e-mail using a Node.js module

Let’s go back to our initial requirements: whenever someone enters their name and e-mail address in our application, we want to send out an e-mail thanking them for participating. We can do this by making use of an NPM module, for example SendGrid.

Windows Azure Mobile Services comes with some NPM modules preinstalled, like SendGrid and Twilio. However we want to make sure we are always using the same version of the NPM package, so let’s install it into our project. WebStorm has a built-in package manager to do this, however Windows Azure Mobile Services requires us to install the module in a non-standard location (the service folder) hence we will use the Terminal tool window to install it.

12

Once finished, we can start working on our e-mail logic. Since we may want to re-use the e-mail logic (and we want to unit test it later), it’s best to create our logic in the shared folder.

13

In our shared module, we can make use of the SendGrid module to create and send an e-mail. We can export our sendThankYouMessage function to consumers of our shared module. In the visitor.insert.js script we can require our shared module and make use of the functionality it exposes. And as an added bonus, WebStorm provides us with autocompletion, code analysis and so on.

14

Once we’ve updated our code, we can transfer our server-side code to Windows Azure Mobile Services. Ctrl+K (or Cmd+K on Mac OS X) allows us to commit and push from within the IDE.

15

Putting our API to the test with the REST client

Once our changes have been deployed, we can test our API. This can be done using one of the client libraries or by making use of WebStorm’s built-in REST client. From the Tools | Test RESTful Web Service menu we can craft our API calls manually.

We can specify the HTTP method to use (POST since we want to insert) and the URL to our Windows Azure Mobile Services endpoint. In the headers section, we can add a Content-Type header and set it to application/json. We also have to specify an API key in the X-ZUMO-APPLICATION header. This API key can be found in the Windows Azure Management Portal. On the right-hand side we can provide the text to post, in this case a JSON-serialized object with some properties.

16

After running the request, we get back response headers and a response body:

17

No error message but an object is being returned? Great, that means our code works (and should also be sending out an e-mail). If something does go wrong, the Logs tab in the Windows Azure portal can be a tremendous help in finding out what went wrong.

Through the toolbar on the left, we can export/import requests, making it easy to create a number of predefined requests that can easily be run over and over for testing the REST API.

Unit testing our logic

With WebStorm we can easily test our JavaScript code and custom Node.js modules. Let’s first set up our IDE. Unit testing can be done using thenodeunit testing framework which we can install using the Node.js package manager.

18

Next, we can create a new Run Configuration from the toolbar selecting Nodeunit as the configuration type and entering all required configuration details. In our case, let’s run all tests from the test directory.

19

Next, we can create a folder that will hold our tests and mark it as a Test Source Root (open the context menu and use Mark Directory As | Test Source Root). Tests for Nodeunit are always considered modules and should export their test functions. Here’s a very basic example which tells Nodeunit to wait for one assertion, assert that a boolean is true and marks the test case completed.

20

Of course we can also test our business logic. It’s best to create separate modules under the shared folder as they will be easier to unit test. However if you do have to test the actual table scripts (like insert functionality), there is a little trick that allows doing just that. The following snippet exports the insert function outside of the table-specific module:

21

We can now test the complete visitor.insert.js module and even provide mocks to work with. The following example loads all our modules and sets up test expectation. We’re also overriding specific functionalities such as the sendThankYouMessage function to just make sure it’s called by our table API logic.

22

The full source code for both the server-side and client-side application can be found onhttps://github.com/maartenba/JetBrainsBoothMobileService.

If you would like to learn more about Windows Azure Mobile Services and work with authentication, push notifications or custom API’s checkout the getting started documentation. And if you haven’t already, give WebStorm a try.

Enjoy!

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)

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:

image

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:

image

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:

image

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…

ASP.NET MVC and jQuery Mobile

jQuery MobileWith the release of Windows Phone 7 last year, I’m really interested in mobile applications. Why? Well, developing for Windows Phone 7 did not require me to learn new things. I can use my current skill set and build cool apps for that platform. But what about the other platforms? If you look at all platforms from a web developer perspective, there’s one library that also allows you to use your existing skill set: jQuery Mobile.

Know HTML? Know jQuery? Know *any* web development language like PHP, RoR or ASP.NET (MVC)? Go ahead and build great looking mobile web apps!

I’ll give you a very short tutorial, just enough to sparkle some interest. After that, it’s up to you.

Getting jQuery Mobile running in ASP.NET MVC

This one is easy. Start a new project and strip out anything you don’t need. After that, modify your master page to something like this:

1 <%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %> 2 3 <!DOCTYPE html> 4 <html> 5 <head runat="server"> 6 <title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title> 7 <link href="../../Content/Site.css" rel="stylesheet" type="text/css" /> 8 9 <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a2/jquery.mobile-1.0a2.min.css" /> 10 <script src="http://code.jquery.com/jquery-1.4.4.min.js"></script> 11 <script src="http://code.jquery.com/mobile/1.0a2/jquery.mobile-1.0a2.min.js"></script> 12 </head> 13 14 <body> 15 <asp:ContentPlaceHolder ID="MainContent" runat="server" /> 16 </body> 17 </html> 18

That’s it: you download all resources from jQuery’s CDN. Optionally, you can also download and host jQuery Mobile on your own server.

Creating a first page

Pages have their own specifics. If you look at the docs, a page typically consists of a div element with a HTML5 data attribute “data-role” “page”. These data attributes are used for anything you would like to accomplish, which means your PC or device needs a HTML5 compatible browser to render jQuery Mobile content. Here’s a simple page (using ASP.NET MVC):

1 <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<RealDolmenMobile.Web.Models.ListPostsModel>" %> 2 3 <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> 4 Page title 5 </asp:Content> 6 7 <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> 8 <div data-role="page"> 9 10 <div data-role="header"> 11 <h1>Title here</h1> 12 </div> 13 14 <div data-role="content"> 15 <p>Contents here</p> 16 </div> 17 18 <div data-role="footer"> 19 <h4>Footer here</h4> 20 </div> 21 </div> 22 </asp:Content>

Building a RSS reader

I’ve been working on a simple sample which formats our RealDolmen blogs into jQuery Mobile UI. Using Argotic as the RSS back-end, this was quite easy to do. First of all, here’s a HomeController that creates a list of posts in a view model. MVC like you’re used to work with:

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.Mvc; 6 using Argotic.Syndication; 7 using RealDolmenMobile.Web.Models; 8 using System.Web.Caching; 9 10 namespace RealDolmenMobile.Web.Controllers 11 { 12 [HandleError] 13 public class HomeController : Controller 14 { 15 private static readonly Uri Feed = new Uri("http://microsoft.realdolmenblogs.com/Syndication.axd"); 16 17 public ActionResult Index() 18 { 19 // Create model 20 var model = new ListPostsModel(); 21 22 GenericSyndicationFeed feed = GenericSyndicationFeed.Create(Feed); 23 foreach (GenericSyndicationItem item in feed.Items) 24 { 25 model.Posts.Add(new PostModel 26 { 27 Title = item.Title, 28 Body = item.Summary, 29 PublishedOn = item.PublishedOn 30 }); 31 } 32 33 return View(model); 34 } 35 }

Next, we need to render this. Again, pure HTML goodness that you’re used working with:

1 <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<RealDolmenMobile.Web.Models.ListPostsModel>" %> 2 3 <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> 4 RealDolmen Blogs 5 </asp:Content> 6 7 <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> 8 <div data-role="page"> 9 10 <div data-role="header"> 11 <h1>RealDolmen Blogs</h1> 12 </div> 13 14 <div data-role="content"> 15 <ul data-role="listview"> 16 <li data-role="list-divider">Posts by employees<span class="ui-li-count"><%:Model.Posts.Count()%></span></li> 17 <% 18 foreach (var post in Model.Posts) 19 { 20 %> 21 <li> 22 <h3><%:Html.ActionLink(post.Title, "Post", new { title = post.Title })%></h3> 23 <p class="ui-li-aside">Published: <%:post.PublishedOn.ToString()%></p> 24 </li> 25 <% 26 } 27 %> 28 </ul> 29 </div> 30 31 <div data-role="footer"> 32 <h4>&nbsp;</h4> 33 </div> 34 </div> 35 </asp:Content>

The result? Not very stunning when looked at with IE8… But fire up Chrome or any other HTML5 capable browser, and here’s what you get:

RealDolmen Blogs Mobile

I’ve asked some people to check http://rd.cloudapp.net (may be offline by the time you read this), and I’ve received confirmation that it looks good on iSomething-devices, a Nokia and some Opera Mobile versions. Nice!

Goodies

The above example may not be that spectacular. The framework does hold some spectacular things! Think dialogs, forms, gestures, animations and a full-blown navigation framework that replaces any form or hyperlink with an AJAX call that is executed in the back-end, displays a nice “loading” screen and automatically generates a “back” button for you.

More examples? Check the manual itself over at http://jquerymobile.com/demos/1.0a2/docs/: this has been built using jQuery Mobile and looks nice!

Conclusion

It’s great! Really, I can just go ahead and build cool mobile web sites / web apps. Unfortunately, the WIndows-market of devices has bad support (due to a lack of HTML 5 support on their devices). This should get fixed in a coming upgrade, but untill then you will not have any luck running these apps on Windows Phone 7… For a complete list of compatible browsers and platforms, check the compatibility matrix.

For those interested, I’ve uploaded my small test app here: RealDolmenMobile.zip (420.38 kb) (note that I've built this as a Windows Azure solution)

Book review: Learning Ext JS

learning-ext-js For a project at one of our customers, we’re building a rich web application using the Coolite web controls in ASP.NET MVC. Coolite is a great product, wrapping all Ext JS widgets in an ASP.NET control. Upon ordering a license for both, we received two free copies of Packt’s “Learning Ext JS”, providing better insight in what’s going on behind the curtains of Coolite.

I only spent one evening reading this book and must admit: it’s really great at getting you started quickly with Ext JS. You’re working with grids, windows and your own grid column renderers, creating a nice looking application which enables you to  manage your DVD collection. As a plus, almost every example features a character or quote from the best movie ever (as an ICT-er): Office Space. This makes it a nice read (at least for me).

The people at Coolite actually did a great job providing this book with their license, as you get a better view of what they do when wrapping Ext JS widgets. If you’re not buying Coolite or a commercial Ext JS license, there’s always Packt’s website offering this book for purchase, too. Nice read!