February 27th, 2018

ASP.NET Core 2.1.0-preview1: Getting started with SignalR

Andrew Stanton-Nurse
Senior Software Engineer

Since 2013, ASP.NET developers have been using SignalR to build real-time web applications. Now, with ASP.NET Core 2.1 Preview 1, we’re bringing SignalR over to ASP.NET Core so you can build real-time web applications with all the benefits of ASP.NET Core. We released an alpha version of this new SignalR back in October that worked with ASP.NET Core 2.0, but now it’s ready for a broader preview and built-in to ASP.NET Core 2.1 (no additional NuGet packages required!). This new version of SignalR gave us a chance to significantly redesign some elements and learn from the lessons of the past, but the core APIs you work with should be very similar. The new design gives us a much more flexible platform on which to build the future of real-time .NET server applications. For now, though, let’s walk through a simple Chat demo to see how it works in ASP.NET Core SignalR.

Prerequisites

In order to complete this tutorial you need the following tools:

  1. .NET Core SDK version 2.1.300-preview1 or higher.
  2. Node JS (just needed for NPM, to download the SignalR JavaScript library; we strongly recommend using at least version 8.9.4 of Node).
  3. Your IDE/Editor of choice.

Building the UI

Let’s start by building a simple UI for a simple chat app. First, create a new Razor pages application using dotnet new:

Add a new page for the chat UI:

You should now have Pages/Chat.cshtml and Pages/Chat.cshtml.cs files in your project. First, open Pages/Chat.cshtml.cs, change the namespace name to match your other page models and add the Authorize attribute to ensure only authenticated users can access the Chat page.

Next, open Pages/Chat.cshtml and add some UI:

The UI we’ve added is fairly simple. We’re going to use ASP.NET Core Identity for authentication, which means the user will be authenticated, and will have a username when we get here. To try it out, use dotnet run to launch the site and Register as a new user. Then navigate to the /Chat endpoint, you should see the following UI: The Chat UI

Writing the server code

In SignalR, you put server-side code in a “Hub”. Hubs contain methods that the SignalR Client allows you to invoke from the browser, much like how an MVC controller has actions that are invoked by issuing HTTP requests. However, unlike an MVC Controller Action, SignalR allows the server to invoke methods on the client as well, allowing you to develop real-time applications that notify users of new content. So, first, we need to build a hub. Back in the root of the project, create a Hubs directory and add a new file to that directory called ChatHub.cs:

Let’s go back over that code a little bit and look at what it does.

First, we have a class inheriting from Hub, which is the base class required for all SignalR Hubs. We apply the [Authorize] attribute to it which restricts access to the Hub to registered users and ensures that Context.User is available for us in the Hub methods. Inside Hub methods, you can use the Clients property to access the clients connected to the hub. We use the .All property, which gives us an object that can be used to send messages to every client connected to the Hub.

When a new client connects, the OnConnectedAsync method will be invoked. We override that method to Send the SendAction message to every client, and provide two arguments: The name of the user, and the action that occurred (in this case, that they “joined” the chat session). We do the same for OnDisconnectedAsync, which is invoked when a client disconnects.

When a client invokes the Send method, we send the SendMessage message to every client, again providing two arguments: The name of the user sending the message and the message itself. Every client will receive this message, including the sending client itself.

To finish off the server-side, we need to add SignalR to our application. We do that in the Startup.cs file. First, add the following to the end of the ConfigureServices method to register the necessary SignalR services into the DI container:

Then, we need to put SignalR into the middleware pipeline, and give our ChatHub hub a URL that the client can reference. We do that by adding these lines to the end of the Configure method:

This configures the hub so that it is available at the URL /hubs/chat. You can use any URL you want, but it can’t match an existing MVC action or Razor Page. NOTE: You’ll need to add a using directive for SignalRTutorial.Hubs in order to use ChatHub in your MapHub call.

Building the client-side

Now that we have the server hub up and running, we need to add code to the Chat.cshtml page to use the client. First, however, we need to get the SignalR JavaScript client and add it to our application. There are many ways you can do this, such as using a bundling tool like Webpack, but here we’re going to go with a fairly simple approach of copying and pasting. First, install the SignalR client using NPM:

You can find the version of the client designed for use in Browsers in node_modules/@aspnet/signalr/dist/browser. There are minified files there as well. For now, let’s just copy the signalr.js file out of that directory and into wwwroot/lib/signalr in the project: SignalR JS file in the lib/wwwroot/signalr folder

Now, we can add JavaScript to our Chat.cshtml page to wire everything up. At the end of the file (after the closing </ul> tag), add the following:

We put our scripts in the Scripts Razor section, in order to ensure they end up at the very bottom of the Layout page. First, we load the signalr.js library we just copied in:

Then, we add a script block for our own code. In that code, we first get references to some DOM elements, and define a helper function to add a new item to the messages-list list. Then, we create a new connection, connecting to the URL we specified back in the Configure method.

At this point, the connection has not yet been opened. We need to call connection.start() to open the connection. However, before we do that we have some set-up to do. First, let’s wire up the “submit” handler for the <form>. When the “Send” button is pressed, this handler will be fired and we want to grab the content of the message text box and send the Send message to the server, passing the message as an argument (we also clear the text box so that the user can enter a new message):

Then, we wire up handlers for the SendMessage and SendAction messages (remember back in the Hub we use the SendAsync method to send those messages, so we need a handler on the client for them):

Finally, we start the connection. The .start method returns a JavaScript Promise object that completes when the connection has been established. Once it’s established, we want to enable the text box and button:

Testing it out

With all that code in place, it should be ready to go. Use dotnet run to launch the app and give it a try! Then, use a Private Browsing window and log in as a different user. You should be able to chat back and forth between the browser windows.

Conclusion

This has been a brief overview of how to get started with SignalR in ASP.NET Core 2.1 Preview 1. Check out the

full code for this tutorial if you’d like to see more details. If you need help, post questions on StackOverflow using the signalr-core tag. Finally, if you think you’ve found a bug, file it on our GitHub repository.

Author

Andrew Stanton-Nurse
Senior Software Engineer

Andrew Stanton-Nurse is an engineer on the ASP.NET team. He joined Microsoft full-time in 2009 after graduating from Simon Fraser University in Vancouver, Canada. Through his career he’s worked on most of the ASP.NET stack, from Web Forms, MVC and the first versions of Razor, all the way up through ASP.NET Core, with a little NuGet thrown in. Andrew lives in Seattle with his wife and two cats.

0 comments

Discussion are closed.