Creating a Self Hosted SignalR 2.0b Server and creating a Windows 8.1 Store Client

Posted by: Sumit Maitra , on 7/18/2013, in Category Windows Store Apps
Views: 50695
Abstract: Create a SignalR 2.0 (beta) Self Hosted server and connect multiple clients including a JavaScript and a Windows 8.1 Client.

SignalR 1.0 was released early this year with ability to Self Host using a custom OWIN implementation. However, the team hasn’t been sitting idle and fast forward six months SignalR 2.0 is already in Beta now. SignalR 2.0 has some major revisions with respect to Owin hosting and support for Portable Client Libraries for the .NET client. This has resulted in better support for SignalR for Windows 8.1 clients. Today we’ll checkout how to self host a SignalR 2.0b server, an HTML client on the OWIN server and a Windows 8 Client that communicates with the Self Hosted SignalR Server.

 


Setting up SignalR and Static files hosting using OWIN components

We are using Visual Studio 2013 Preview to build this sample. This will enable us to build a Windows 8.1 client. The following section is very similar to the steps in our previous article discussing OWIN/Katana and SignalR Self Hosting. The major difference being change in the name of the Host from WebApplication to WebApp and the fact that we are using SignalR 2.0 prerelease components as opposed to SignalR 1.x components.

Setting Up SignalR 2.0b Self Hosting

We start off with a simple console application called SelfHostSignalR20. Once the project is ready, we start installing the dependencies from Nuget.

1. OWIN Hosting: This has the WebApp class that provides us the bootstrapping to do ‘self-hosting’. To install it, we use the following Nuget command. Note the –pre attributes every where in the following commands we are using Pre-release beta components, so some changes are likely to be expected by the time these components go live.

PM> Install-Package Microsoft.Owin.Hosting –pre

2. OWIN HttpListener: This provides us with the bare-bones Http Listener

PM> Install-Package Microsoft.Owin.Host.HttpListener –pre

3. Next we get SignalR: For Self Hosting, SignalR has a separate Nuget package that can actually download the above dependencies if required.

PM> Install-Package Microsoft.AspNet.SignalR.SelfHost –pre

4. We update our Program.cs as follows

using Microsoft.Owin.Hosting;
using System;

namespace SelfHostSignalR20
{
class Program
{
  static string url = "
http://localhost:8080";
  static void Main(string[] args)
  {
   using (WebApp.Start<Startup>(url))
   {
    Console.WriteLine("Server running on {0}", url);
    Console.ReadLine();
   }
  }
}
}

This initializes the OWIN WebApp host using the ‘Startup’ class and the URL of http://localhost:8080. Next we’ll see what this magic Startup type does.

5. We add a class called Startup.cs. This class name Startup and the method Configuration with an IAppBuilder input parameter is a convention that Katana looks out for and uses to configure Middleware modules.

using Microsoft.AspNet.SignalR;
using Owin;
using System.IO;
using System.Reflection;
namespace SelfHostSignalR20
{
public class Startup
{
  public void Configuration(IAppBuilder app)
  {
   // Turn cross domain on
   var config = new HubConfiguration { EnableCrossDomain = true };
   // This will map out to
http://localhost:8080/signalr
   app.MapHubs(config);
  }
}
}

Next we hook up a SignalR hub.

6. Add a class called MyHub that has one function SendMessage. The SendMessage function lobs back the Message it receives, to all connected clients.

using Microsoft.AspNet.SignalR;
namespace SelfHostSignalR20
{
public class MyHub : Hub
{
  public void Send(string message)
  {
   Clients.All.addMessage(message);
  }
}
}

At this point, we have SignalR ready to go as a SelfHosted Server. However there are no clients connecting to it. We can confirm that the server is good by running the application and then visiting the http://localhost:8080/signal/hubs, this would download the JavaScript proxy class generated for the Hub class we created above.

With SignalR ready, let’s setup Static Hosting and a JavaScript client.

Setting up Static Hosting and a JavaScript SignalR client

Here things are a little hairy with alpha versions and specific version numbers to retrieve Nuget packages otherwise not available. Static Hosting for OWIN is still pretty much ‘work in progress’ so what we are using the next steps is the bleeding edge of stuff.

Step 1: We install Static HTML hosting middleware modules as follows

PM> Install-Package Microsoft.Owin.FileSystems –version 0.20-alpha-20220-88

PM> Install-Package Microsoft.Owin.StaticFiles –version 0.20-alpha-20220-88

Step 2: Next we install SignalR JavaScript files using the following Nuget command

PM> Install-Package Microsoft.AspNet.SignalR.Js –pre

This adds a Scripts folder with the SignalR JavaScript and jQuery dependency. We can update the jQuery version from 1.6.x to the latest if we want using the update-package command

PM> Update-Package jQuery

Step 3: Once installed, we get back to the Startup class and add the following lines after app.MapHubs(…)

string exeFolder =
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string webFolder = Path.Combine(exeFolder, "Web");
app.UseStaticFiles(webFolder);

These commands  setup a folder called ‘Web’ as the root of the HTTP server. All files under Web will be statically hosted.

Step 4: We now add a plain vanilla html file to the Web folder called home.html. We also move the Scripts folder added in Step 2 above to the Web folder because we want these scripts to be hosted along with our html file.

We add the following markup to setup two input elements (one to show incoming data, one to input outgoing data) and a button to send the text in the outgoing input element.

<!DOCTYPE html>
<html>
<head>
<title>SignalR Self Host</title>
<script src="Scripts/jquery-2.0.2.min.js"></script>
<script src="Scripts/jquery.signalR-2.0.0-beta2.min.js"></script>
<script src="../signalr/hubs"></script>
</head>
<body>
<h1>SignalR Self Hosting</h1>
  <div>
   <div>
    <textarea id="messagesText" rows="15" style="width:100%"></textarea>
   </div>
  <div>
  <textarea id="newMessage" rows="3"></textarea>
  <button id="sendMessage">Send</button>
</div>
</div>

Next we add the JavaScript that creates the client instance and registers events that will call the server. In our case, click on the ‘sendMessage’ button will call the Hub’s (on the server) sendMessage function via the proxy. Similarly we have a client side method addMessage that is invoked from the server, and when invoked it updates the messagesText text box. The complete code is as follows:

<script type="text/javascript">
var hub = $.connection.myHub;
  $(document).ready(function () {
    $msgText = $("#messagesText"),
    $newMessage = $("#newMessage");
   });
   hub.client.addMessage = function (message) {
    $msgText.text($msgText.text() + "\r\n" + message);
   }
   $.connection.hub.start().done(function () {
    $(document).on('click', '#sendMessage', function () {
      hub.server.send($newMessage.val());
      $newMessage.val('');
    });
   });
</script>

With this our standalone, ASP.NET free OWIN based Self Hosted SignalR app is ready. If we run it now and open two browsers side by side, we’ll see messages from one dialog being sent to the others.

Building a Windows 8.1 SignalR Client

Having a JavaScript client for SignalR was no biggie, but what would it take if we were to do the same thing in a Windows 8.1 Store app? Well let’s find out.

Before 2.0, SignalR’s .NET client could be used in WPF and Winforms apps but not in WinRT XAML apps. Instead for WinRT, we had to use the JavaScript client. But now the .NET client has been ported as a Portable Client Library enabling it to be used in WinRT XAML Apps.

Today we’ll use the Microsoft.AspNet.SignalR.Client package from Nuget to help us build a WinRT/XAML SignalR client for the above Standalone SignalR server.

Adding a WinRT Project to the Solution

We had started off with a Console App. If you are using any Visual Studio 2013 (preview) edition other than the Express edition, you can add the WinRT project to the same Solution. If not, you can start with a new WinRT Blank project template.

win8-client-project

In the MainPage.Xaml, update the markup to contain a ‘Connect’ button, and ‘IncomingMessages’ textblock, an ‘OutgoingMessage’ textbox and a ‘Send’ button. The final UI looks as follows

win-81-client

The corresponding markup is as follows

<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<TextBlock HorizontalAlignment="Left" Margin="120,80,0,0" TextWrapping="Wrap"
  Text="SignalR WinRT Client" VerticalAlignment="Top" Height="45" Width="340"
  FontSize="35" />
<TextBox Margin="120,142,197,0" TextWrapping="Wrap" Name="ServerPath"
  Text="
http://localhost:8080/" VerticalAlignment="Top" FontSize="22"
  Height="43"/>
<Button Content="Connect" HorizontalAlignment="Right" Margin="0,137,77,0"
  VerticalAlignment="Top" Click="Button_Click" Height="51" FontSize="18"
  Width="118"/>
<TextBlock x:Name="IncomingMessages" Height="266" Margin="120,190,80,0"
  TextWrapping="Wrap" Text="" VerticalAlignment="Top"/>
<TextBox x:Name="OutgoingMessage" Height="80" Margin="120,461,197,0"
  PlaceholderText="Message to Send" TextWrapping="Wrap" Text=""
  VerticalAlignment="Top" FontSize="22" />
<Button Content="Send" HorizontalAlignment="Right" Margin="0,458,77,0"
  VerticalAlignment="Top" Width="118" Height="86" Click="SendButtonClick"/>
</Grid>

For this sample I’ve not used Model Binding, instead the code behind looks as follows:

private async void Button_Click(object sender, RoutedEventArgs e)
{
if (hubConnection == null)
{
  hubConnection = new HubConnection(ServerPath.Text);
  myHubProxy = hubConnection.CreateHubProxy("MyHub");
  myHubProxy.On<string>("addMessage", OnAddMessage);
  await hubConnection.Start();
}
}
volatile string message = "";
private async void OnAddMessage(string msg)
{
message = msg;
await dispatcher.RunAsync(CoreDispatcherPriority.Normal, handler);
}
private void handler()
{
IncomingMessages.Text = IncomingMessages.Text + Environment.NewLine + message;
}
private void SendButtonClick(object sender, RoutedEventArgs e)
{
myHubProxy.Invoke("Send", OutgoingMessage.Text);
OutgoingMessage.Text = string.Empty;
}

Initializing Connection and Handling Server Side actions

The Button_Click event handler initiates the HubConnection using the Server Path provided. By default it is pointing to http://localhost:8080/

Once the Hub Proxy is created, we assign client side event handlers (that the server can call) using the myHubProxy.On<T> syntax. This method takes the name of the server-side method and Action<T>. In our case, we call the OnAddMessage action method, which saves the incoming message in the ‘message’ variable and then updates the UI via dispatch handler. The dispatch handler method simply updates the IncomingMessages text block.

Sending messages to the Hub

The SendButtonClick event handler uses the myHubProxy created during the connection initialization to Invoke server side methods. The first parameter of the Invoke function is the server side method name and next we have the list of parameters accepted by the server.

With this minimal code, we are now ready to demonstrate interaction between a WinRT Client and two JavaScript web clients, talking to each other over SignalR running on (not IIS) but simply an OWIN compliant host independent of IIS

Demo

Now we’ll setup the solution to start both the projects together (if you have separate solutions you can run them separately). We split the screen in to the new Windows 8.1 50:50 split, with one side containing the WinRT app and the other split between the IE and FF browsers, pointing to the home.html.

demo-start

As we can see, the 50:50 split is a pretty effective screen configuration. Once the server has started, we split up the screen as above and then the clients send messages. The messages are broadcasted for all clients receive all messages. As seen below, all three clients have exchanged messages with each other

demo-end

First WinRT sends out the message “Hello IE and FF”, then IE sends out “Hello WinRT” and finally Firefox sends out “Whassup folks!”.

Recap and Conclusion

To recap, we were able to setup SignalR on a OWIN powered Host and create a simple HTML+JavaScript client without involving any of the heavy weight infrastructure or frameworks. Next we were able to create a functional Windows 8.1 C# + XAML app that could communicate with our barebones SignalR server.

The scope of these kinds of applications at the moment are limited to compact notification and messaging services, but once it goes live, OWIN based servers will gain performance from their granular and mix-and-match type of architecture. At that point OWIN + Web API + SignalR could well become a full-fledged service platform. So watch out for lots of action in the OWIN space.

Download the entire source code of this article (Github)

What Others Are Reading!
Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+

Author
Sumit is a .NET consultant and has been working on Microsoft Technologies since his college days. He edits, he codes and he manages content when at work. C# is his first love, but he is often seen flirting with Java and Objective C. You can follow him on twitter at @sumitkm or email him at sumitkm [at] gmail


Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!
Comment posted by D.Chamberland on Saturday, April 12, 2014 3:03 PM
Great work...
This is a great powerful scenario option to explore not only on WinRT  but I assume on Windows Phone devices as well. Windows Phone 8.1 coding now is available with WinJS 2.0 and that's a new combination which will really worth taking a close look at.
Comment posted by Anto on Wednesday, May 20, 2015 6:03 AM
Hello, I am using SignalR in WinForms application. Everything works fine on my local network, When setup this application to work on Windows Server, I got message "not respond..."
On windows server I added inbound rules, port, also installed web socket,
Can you give me advice how to setup SingalR in winworms on server..?
my clients are also win forms applications
Regards
Comment posted by Anto on Wednesday, May 20, 2015 6:46 AM
Hello, I am using SignalR in WinForms application. Everything works fine on my local network, When setup this application to work on Windows Server, I got message "not respond..."
On windows server I added inbound rules, port, also installed web socket,
Can you give me advice how to setup SingalR in winworms on server..?
my clients are also win forms applications
Regards
Comment posted by Anand on Wednesday, May 20, 2015 7:23 AM
Hello... nice tutorial..
How can I connect using signalR hub hosted in "self hosted" environment using silverlight client?

Categories

JOIN OUR COMMUNITY

POPULAR ARTICLES

FREE .NET MAGAZINES

Free DNC .NET Magazine

Tags

JQUERY COOKBOOK

jQuery CookBook