Using SignalR in ASP.NET Core & React to Send Messages
Using SignalR in ASP.NET Core & React to Send Messages
2nd July 2020
We did a live stream where we integrated SignalR with ASP.NET Core and React.
We went ahead and built a system where you can send messages in a React app. From there, it used SignalR to send the message to the ASP.NET Core app. Once the ASP.NET Core app got the message, it sent it's own message back to the React app.
We are going to recap on the steps we went through in that demo to successfully integrate SignalR with React and ASP.NET Core.
Creating The Applications
Firstly, we built a ASP.NET Core MVC API application. Next, we built a React application in the same directory as the ASP.NET Core application and integrated the two together. Thereafter, we integrated SignalR into both applications to enable us to communicate between ASP.NET Core and React.
Create The ASP.NET Core MVC API Application
We used Visual Studio to create our ASP.NET Core MVC API application. Using Visual Studio Templates, we selected ASP.NET Core Web Application and choose the API template.
Now, we could of used the React.js template at this stage, but there are a couple of reasons why we didn't:
We are not too sure how to use this template, and create the React application with TypeScript. This template always creates the React app with JavaScript.
It's good to have an understanding on how to integrate a React app with a ASP.NET Core app.
Create React App
We opened up the terminal in Visual Studio Code, run a CD command to the directory where the ASP.NET Core application exists. Then, we ran the following command to create the React app:
Now that we have created both applications, we need to make some configuration changes to our ASP.NET Core application. But first, we need to install the following NuGet packages into our ASP.NET Core application:
Microsoft.AspNetCore.SpaServices
Microsoft.AspNetCore.SpaServices.Extensions
From there, we can open up our Startup class and make the configuration changes necessary.
Inside the ConfigureServices method, add the following line of code:
This points the source path to our React app. In addition, it allows us to run the React Development Server when in Development. So, when we make a change in React, the React application is automatically rebuilt without having to restart the ASP.NET Core application.
It's worth checking at this stage that your ASP.NET Core is integrated properly with React. Run the application to check. The React app should reside in https://localhost:{port}/clientapp.
SignalR Integration
Assuming your application is running fine, it's time to integrate SignalR. SignalR needs to be integrated in both the ASP.NET Core and React applications.
React
Firstly, we will integrate SignalR into our React app by running acommand line in the terminal in Visual Studio Code. Just make sure that you are pointing to the "clientapp" folder.
CD [PathToASPNETCoreApp]/clientapp
Then you can run this command line to install SignalR into React:
yarn add @microsoft/signalr
ASP.NET Core Integration
Next, we need to integrate it into our ASP.NET Core application. You will need to add the following NuGet package in-order to do this:
Microsoft.AspNetCore.SignalR.Client
From there, we need to make a change in our Startup class. Inside the ConfigureServices method, add the following:
services.AddSignalR();
Now, we have to create a new SignalR Hub which is very straight forward. Create a new class called MessageHub. We need to ensure that this class inherits the Hub class.
// MessageHub.cs
public class MessageHub : Hub
{
}
Finally, we need to map our hub to a route. The React app will use this route to connect to the right hub. Back in the Startup class, and the Configure method, there should be a app.UseEndPoints method. Add the following code to the top of this method:
endpoints.MapHub<MessageHub>("/message");
This routes the MessageHub to /message.
API Endpoint
We need to create an endpoint where we can fire our messages to. For this, we have created a MessageController. The MessageController will route to /api/message. Inside this controller, we will integrate a Create method which will accept a HTTP Post verb.
The Create method will have a parameter of MessagePost. Inside the MessagePost, there will be a Message property. When we send the payload over to this action, we will send it as JSON. Inside the JSON, there will be a Message key. This Message key will bind with the Message property in the MessagePost class.
Inside the Create method, we use the MessageHub to send a message to all clients connected through SignalR. The MessageHub is injected through dependency injection through the IHubContext interface. Clients can hook into a virtual "sendToReact" method that will triggered when we invoke it.
// MessageController.cs
[Route("/api/message")]
[ApiController]
public class MessageController : Controller
{
protected readonly IHubContext<MessageHub> _messageHub;
public MessageController([NotNull] IHubContext<MessageHub> messageHub)
{
_messageHub = messageHub;
}
[HttpPost]
public async Task<IActionResult> Create(MessagePost messagePost)
{
await _messageHub.Clients.All.SendAsync("sendToReact", "The message '" +
messagePost.Message + "' has been received");
return Ok();
}
}
public class MessagePost
{
public virtual string Message { get; set; }
}
It's worth at this point testing this method in Postman to check that you are getting a 200 response:
Use React App To Send The Messages
We now go ahead and change the code in App.tsx. The point here is to build up a SignalR connection to /message (which translates to the MessageHub).
Once we've done that, we create a string array. This array will list all the messages that we have received.
Then we create a separate function component (FC). Called Messages, this will hook into the "sendToReact" method that we use in our ASP.NET Core application through the MessageController. When this method receives a message, we push it to our string array. Then, we use the useState method to update the list of messages received to the client.
Finally, we create a new function component to send the message. This will have a text box and a submit button. When the submit button is clicked, it will throw an API POST call to /api/message. If you remember, it's the Create method in our MessageController. It will then return a message back to any clients connected.
To see the working demo in action, you can watch back our live stream. This will take you through the processes required. And by watching the video, you can follow along and code to get the application working.
Going Forward...
We integrated SignalR to send messages to all clients. However, with SignalR, you can focus on a particular user. That would be handy if you wanted to integrate a chat application. You can also set up multiple SignalR hubs if you need to. There is a lot of flexibility around it.
About the author
David Grace
Senior .NET web developer | ASP.NET Core | C# | Software developer