ASP.NET Core SignalR for Windows 10 UWP App

It has been quite sometimes I have not use ASP.NET SignalR. As you may know that currently we can use ASP.NET Core for creating WebAPI, it come to my mind to try SignalR service using ASP.NET Core and with Windows 10 UWP as the client for consuming the SignalR service. This blog is about just that, I divide the project into two, that is the SignalR service server and SignalR client which is inside Windows 10 UWP app. So let’s start.

SignalR Service Server

Let’s begin with creating the ASP.NET Core project, fire up Visual Studio 2015 with — of course .NET Core installed.

ASP.Net Core Create New Project

Once created, open the project.json file or Right-Click the References on the Solution Explorer and choose Manage NuGet packages and add the SignalR package library.

However, when I try to find the SignalR (see below image), I cannot find the one that is compatible with ASP.NET Core 1.0. The one that is in NuGet repository that is Microsoft.AspNet.SignalR is for .NET Framework with version is 2.2.1.

Adding SignalR Library

As confusing as it looks, I try to look at SignalR roadmap on the ASP.NET Core Roadmap and apparently it is still under development and it will be release together with the of .NET Core v1.2 on Q1 2017. Not too bad for the time and we actually also can start using the SignalR development bits and that is what I did in here.

I went and look at the SignalR source code on GitHub to see what we can find. The good thing, there is also a sample file there. If you look at the source code, there is a file called NuGet.Config which has this code;

<?xml version="1.0" encoding="utf-8"?>
<configuration>
 <packageSources>
 <clear/>
 <add key="aspnetcidev" value="https://dotnet.myget.org/F/aspnetcore-ci-dev/api/v3/index.json"/>
 <add key="api.nuget.org" value="https://api.nuget.org/v3/index.json"/>
 </packageSources>
</configuration>
 

Apparently, we can use the bits from MyGet.org which is the .NET Foundation private repository for projects maintainers. Well, we can also use it for testing, so we follow them. You can create the NuGet.Config file on the project and add the XML code above. Or, if you also would like to test or do some experiment with others development bits, you can add the MyGet package source link from Visual Studio settings. Go to Visual Studio menu Tools -> Options. And look for NuGet Package Manager -> Package Sources, and add the link;

MyGet Package Source

If you have this on the settings, you won’t need to add the NuGet.Config file again.

Now, go back and open the project.json and add this two lines;

"Microsoft.AspNetCore.SignalR.Server": "0.2.0-*",
"Microsoft.AspNetCore.WebSockets": "0.2.0-*",

And also add the Microsoft.AspNetCore.Cors which is already available in .NET Core 1.0 RTM.

"Microsoft.AspNetCore.Cors": "1.0.0"

And save. So, it should show something like this;

Add SignalR Package

Once the package restored, you can go to the References folder and view the package version. At this point of time in my project is showing this version;

Microsoft.AspNetCore.SignalR.Server: 0.2.0-alpha1-22118
Microsoft.AspNetCore.WebSockets: 0.2.0-alpha1-22118

There you go. Now, since we already have the SignalR package library, we can now add the SignalR hub. To do this, you can add new Folder on the project, just name it as Hubs. And add new empty C# class file named MySignalRHub.cs.

Inside MySignalRHub.cs, add this code;

using Microsoft.AspNetCore.SignalR;
using Microsoft.AspNetCore.SignalR.Hubs;

namespace AspNetCoreSignalR.Hubs
{
    [HubName("updater")]
    public class MySignalRHub : Hub
    {
        public void NewUpdate(string command, double state)
        {
            Clients.Others.newUpdate(command, state);
        }
    }
}
 
 

Here is the view on Visual Studio.

MySignalRHub.cs file

For the final part, we need to configure the SignalR service middleware. Open the Startup.cs file and add/update with the following code below;

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

namespace AspNetCoreSignalR
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddCors();
            services.AddSignalR(
                options => options.Hubs.EnableDetailedErrors = true);
        }

        public void Configure(IApplicationBuilder app,
            IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole();
            if (env.IsDevelopment()) app.UseDeveloperExceptionPage();

            app.UseCors(cors =>
            {
                cors.AllowAnyHeader();
                cors.AllowAnyOrigin();
                cors.AllowAnyMethod();
            });

            app.UseWebSockets();
            app.UseSignalR();
        }
    }
}
 
 

We enable the CORS so it can be use once the SignalR server deployed to Azure and the client is on different domain or network origin. If we did not enable the CORS, than we only can use the SignalR on the same network domain. If the SignalR domain is local network than the client must also be on the same local network to be able to connect to SignalR. In my example above, I just enable all for the sake of the demo. You should not do this in real world and you need to secure the SignalR as well.

And that’s it. You have SignalR server. Let’s test this by Debug Run it (F5). Once it runs, go to the URL link and append with /signalr/hubs. In my case, the link is this;

SignalR Test

You should be able to see a JavaScript generated by the SignalR server. This JavaScript can be consume in HTML document as reference link if you want to use using JavaScript in HTML document. We are half way to finish. However, we would like to consume the SignalR from Azure. So, you also can test with multiple devices such as from Windows 10 Desktop PC or Windows 10 Mobile (if you have one).

Deploying ASP.NET Core SignalR to Azure Web App

If you already have not install the Microsoft Azure SDK, you need to download and install it first. You can also directly create and deploy the Web App from Visual Studio. However, in this example, I will make the empty Web App on Azure first than deploy the SignalR. To start, open the Azure Portal and create a new empty Web App.

Azure Create Web App

Fill in the parameters field of your choice. Once it is done, let’s do some small configuration changes on the Web App Application Settings panel. Enable the Web Sockets.

Web App Application Settings

Now, on the solution explorer in Visual Studio, Right-Click the project and choose Publish. On the publish target Profile, choose the Microsoft Azure App Service option.

Publish Profile

than choose your Subscription as well as the Azure Resource of the Web App that you just created previously. If it is not showing up on the dialog, than you need to make sure that the empty Web App is available. Mine called DemoResources and the Web App name is simplesignalr.

App Service Dialog

Click okay than click the Publish button on the dialog. Once is published, it will automatically open the browser and point to the site. You need to test by concatting the link with /signalr/hubs. Here is for my case;

Browse SignalR Hubs

And there you go, you just deployed the SignalR service on Azure. We can start developing the client as Windows 10 UWP app to consume the SignalR service.

SignalR Client using Windows 10 UWP

Create a new Windows 10 UWP app project. I just leave the name as App1.

Create Windows 10 UWP Project

Open the project.json and add the SignalR client package on the dependencies part;

"Microsoft.AspNet.SignalR.Client": "2.2.1"

Interestingly, you can use the .NET Framework package library as Windows 10 UWP can only run on Windows 10. Since SignalR is messaging, and as long as the client and server understand the protocol, it will work.

Add SignalR Client package

Save it. Now, open the MainPage.xaml file and add some controls on the Grid element, that is the TextBlock control and Slider control.

<Page
     x:Class="App1.MainPage"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:local="using:App1"
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     mc:Ignorable="d">

     <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
         <Grid.RowDefinitions>
             <RowDefinition Height="Auto" />
             <RowDefinition />
         </Grid.RowDefinitions>
         <TextBlock x:Name="textbl" Grid.Row="0" Margin="20" />
         <Slider x:Name="slider" Grid.Row="1" Margin="20" />
     </Grid>
</Page>

Save it. Add a folder called Services on the project file. This folder is just for tiding up the code, so is not scattered on the main project folder.

Add an empty class file named ValueChangedEventArgs.cs. This file if just for helper for an event later on. Add this code on the ValueChangedEventArgs.cs.

using System;

namespace App1
{
    public class ValueChangedEventArgs : EventArgs
    {
        public string Command { get; private set; }
        public double State { get; private set; }
        public ValueChangedEventArgs(string command, double state)
        {
            Command = command;
            State = state;
        }
    }
}

Next, create an empty file named SignalRClient.cs, also on the Services folder. And add this code below,

using Microsoft.AspNet.SignalR.Client;
using System;

namespace App1
{
    public class SignalRClient
    {
        private IHubProxy _hub;
        public event EventHandler ValueChanged;

        public IHubProxy SignalRHub { get { return _hub; } }

        public async void InitializeSignalR()
        {
            var hubConnection = new HubConnection("http://[use your web app name].azurewebsites.net/signalr");
            _hub = hubConnection.CreateHubProxy("updater");

            _hub.On<string, double>("newUpdate",
                (command, state) => ValueChanged?.Invoke(this, new ValueChangedEventArgs(command, state)));

            await hubConnection.Start();

        }
    }
}

Remember, on the HubConnection(“… URL …”) above, make sure to update the URL link to your own Azure Web App link. Otherwise, you will get error and the app will just close.

Finally, add/update some code behind MainPage.xaml.cs file. Open it and add these lines;

using Microsoft.AspNet.SignalR.Client;
using System;
using System.Threading.Tasks;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace App1
{
    public sealed partial class MainPage : Page
    {
        private IHubProxy hub;

        public MainPage()
        {
            InitializeComponent();
            Loaded += MainPage_Loaded;
        }

        private void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            InitSignalR();
        }

        private async void InitSignalR()
        {
            slider.IsEnabled = false;
            textbl.Text = "Connecting to SignalR Server";

            await Task.Run(async () =>
            {
                SignalRClient signalR = new SignalRClient();
                signalR.InitializeSignalR();
                signalR.ValueChanged += ValueChanged;
                hub = signalR.SignalRHub;

                await Dispatcher.RunAsync(
                    CoreDispatcherPriority.Normal, () =>
                    {
                        slider.ValueChanged += (s, e) => textbl.Text = e.NewValue.ToString();
                        slider.PointerMoved += (s, e) => SendMessage("SLIDER", slider.Value);

                        textbl.Text = "Connected...!";
                        slider.IsEnabled = true;
                    });
            });
        }

        private async void ValueChanged(object sender, ValueChangedEventArgs e)
        {
            await Dispatcher.RunAsync(
                CoreDispatcherPriority.Normal, () =>
                {
                    slider.Value = e.State;
                    textbl.Text = $"{e.Command}: {e.State}";
                });
        }

        private async void SendMessage(string command, double state)
        {
            try
            {
                await hub?.Invoke("newUpdate",
                    new object[] { command, state });
            }
            catch { }
        }

    }
}

And there you have it. Build and deploy to Windows 10. In my test, I also deploy to Windows 10 Mobile device which is Microsoft Lumia 640.

Demo

Enjoy and happy coding…!

Entire Source Code on my GitHub.

🙂

One thought on “ASP.NET Core SignalR for Windows 10 UWP App

Leave a Comment