Giving the ValuesController superpowers with SignalR Core

Getting started with this amazing library.

With .NET Core 2.1 approaching very soon one of the most exciting additions (along with many others) is the release of SignalR Core.

The original SignalR for ASP.NET was a powerful client-server library for creating real-time web applications, however with the release of ASP.NET Core this functionality was not ported over at release.

I have been using SignalR Core for a few months now, eagerly awaiting its official release, and for the product I am working on we leverage it’s power throughout the solution. Despite the many breaking changes that we have had to overcome whilst using the preview builds of the library (as was to be expected) the SignalR Core team have done a fantastic job and it's clear their work ethic is unparalleled.

This article will go through just how easy it is to get started with signalr in an existing ASP.NET Core WebAPI and some of the cool things the library can do.

If you’d prefer to follow along with source you can download it from GitHub.

Setting up SignalR

Before we get into actually playing with SignalR, we need to set it up. I would recommend for this tutorial you install the .NET Core 2.1 Preview as it will work the best for the purposes of this tutorial. You will also need a client for this solution, I have chosen to scaffold a Vue TypeScript solution using vue-cli but you can use whatever you want as the SignalR JS Client is completely un-opinionated.

In your server project install SignalR core and restore dependencies with:

dotnet add package Microsoft.AspNetCore.SignalR --version 1.0.0-preview2-final

dotnet restore

You won’t need to append the version on the final release, however for the preview you should as .NET CLI will throw an error.

Once added, open your Startup.cs file and add the service in ConfigureServices :

As well as use the service in Configure :

Don’t worry about the empty braces, we’ll be adding our Hub to that soon enough. Run your project using dotnet watch run and go to https://localhost:5001/api/values and you should see the values array.

Our First Hub

First thing you’ll want to do is create a new folder called Hubs in your backend project, inside we’ll add a file called ValuesHub.cs .

SignalR has various types of Hubs, for this we’ll be creating Hubs which using an interface to layout the types of events that can occur on that hub. It makes more sense with an example;

The tasks on this interface essentially define the events the client and server will be able to send and receive over . This can be expanded as much as needs be and doesn’t necessarily require an implementation in the API.

Now that we’ve defined the client, we can create the Hub. Before we start lets have a look at the metadata for the Hub class:

As you can see it’s relatively slim for what we have to remember. The OnConnectedAsync and OnDisconnectedAsync methods are the only existing methods with the rest to be defined by us.

For the most part the hub is a 1–1 mapping of the client interface. This doesn’t have to be the case, the tasks in a SignalR Hub can do whatever you need it to and don’t necessary need to align with the client’s capabilities.

Now that we have a hub, let’s use it in our Startup file:

That’s it, we can now connect to the hub using the SignalR clients! That being said, it doesn’t do much so let’s add some functionality to the ValuesController .

Using Hubs through Dependency Injection

Whilst I would never recommend this in any form of development or production where you actually need to do things the right way, let's use a static list of strings as our source for values and update some of the methods to use this source:

I’m so sorry about this

Once that's been implemented, you should be able to essentially use the Source as an in-memory store for values (try it in Postman, it does work…).

Now using our Hub, we’re going to add real-time updates for the values controller so that any client listening knows when a value is added or deleted from the source. As with any other ASP.NET Core service, we can access the Hub through Dependency Injection. We can’t directly reference the Hub and instead need to reference a HubContext<ValuesHub> which will expose the Hub’s service and allow us to invoke it’s events.

With access to the Hub, we can now use the access all the events that we implemented before using the SendAsync method. By calling this method on Clients.All we are able to notify everyone who is listening to the hub, the first param of SendAsync the name of the event with the second value being the data that is being sent.

With those implementations, it's safe to say that we're done with the API for now. From this snippet of code we know that when any value is added or deleted all listening clients will be notified of the change.

The Client

For the client side of things, I'll be using the SignalR JS library and we'll be making a basic SPA to view the values in a list (the list being updated in realtime using SignalR Core). I chose Vue.js with TypeScript as the framework for my client but in all honestly there's really no need to use a specific library or any library at all I just love Vue. I do recommend you use something that support JavaScript Modules however as I will be using those to import the SignalR client.

If you want to follow along with Vue, I highly recommend you create a project using the Vue CLI ( npm install vue-cli -g ) and scaffold a new project ( vue create project-name ).

The first step is to install the client using npm install @aspnet/signalr . This does come with TypeScript definitions so need to worry about types if you're a TypeScript user like myself. No matter how you’re writing your client, the first thing you’ll need to do is query the API for values. This will only need to happen on the load of the page, as past this point we'll be using SignalR to keep it updated. In my code I called the following in the beforeMount event of my Vue component:

Using a tool like Postman, add some values to the API. Populate a list using the request above ( <ul v-for="v in values" :key="v"> ) and you should have something that looks like this:

Beautiful

Using Postman is a bit of a pain however, so let’s add some code and a form for adding values:

Same goes for deleting

After adding some UI for these methods, my final app looked like this:

Whilst this is good and all, we still haven’t used SignalR yet. If you are using modules you’ll need to import it like so…

import { HubConnection, TransportType } from "@aspnet/signalr";

If you are not using modules you’ll need to reference "node_modules/@aspnet/signalr/dist/browser/signalr.js" in a script tag.

To connect to the hub, we need to use the HubConnection class:

HubConnection takes in 2 arguments, the first being the URL to the Hub (that we defined in MapHub and the second being an object full of options. I like to ensure that we’re using the TransportType.WebSockets as not defining it can result in errors on connection.

Using the on method you define the listeners for the events which are emitted by both clients and servers. In the example above, we assume that value is the string that is being added or deleted.

This is all that is required to setup the SignalR client, once the event listeners have been added we can call start and that’s it; we are now connected to the ValuesHub. The client will continue to stay updated after its been opened, opening multiple windows side by side will also show you that all clients will have the same values on screen.

Adding SignalR Core to an existing WebAPI is incredibly simple and as has been demonstrated the benefits of using it in your applications can be seen with as little as 10 lines of code.

If you liked this article please give it a clap or 7 and remember the source code for this article is available on Github.