Real-Time Notifications Using Blazor and SignalR from scratch

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
signal R and Blazer webassembly it seems like a perfect match and in today's video I'm going to show you how to send notifications from your backend using signalr to a client implemented with blazer webassembly I'm going to start from an empty asp.net core web API and the default Blazer web assembly application that you get scaffolded out of the box if you start both of the applications you're going to see the empty Swagger UI for the backend because we don't have any endpoints and in the Blazer client you're going to be welcomed with the home component a counter component where you can increment the count by clicking the button and it's going to refresh the value on the user interface and the fetch data component which gets the data from a Json file and then renders it on the screen so let's see how we're going to use signalr to connect the Blazer client with the back end the first thing I need to do is to add the required services in my backend project for working with signalr so I'm just going to call add signalr then I need to Define My Hub which is the central component that my clients will connect to so let's call this the notifications Hub and I'm going to create this class it's going to implement the Hub Base Class and this is a class exposed by signalr which you can use to implement messaging between your server which is your Hub and your client The Hub Base Class isn't strongly typed so what I like to do is to define a client interface let's call this the I notification client and this interface will contain the methods that I can call on my signalr client so in our case this is going to be the Blazer application so let's define an asynchronous method and let's just call it receive notification it's going to have one argument which is going to be the message that we're going to send from the server to our client and then the client is going to render these messages on the screen so how do you make a hub strongly typed well you have to use the generic variant of the Hub Base Class and you specify your client interface now we can only call the methods that are Exposed on the inertification client inside of the notifications Hub so I'm going to override the unconnected async method and I'm going to add some additional code inside but I'm first going to take care of the base call to the unconnected async and now what I want to do is as soon as a new client connects to my notifications Hub I want to send them a message back so here's what I'm going to do I can reference the client's property to access my signalr clients and I can talk to a specific client by calling the client method it requires a connection ID and I can access the connection ID from The Hub caller context it contains the connection ID property which is the client that connected to our Blazer Hub right now so let's use this to access the specific client and I'm just going to send them a message back and you'll see that I have access to the receive notification method this is because I'm using a strongly typed client and the methods that I defined on the client interface are exposed inside of my Hub so let's call the receive notification method and here's what I'm going to send to my client so thank you for connecting and I'm going to send them an identifier which I'm going to pull from The Hub caller context and notice that we have access to the claims principle in the user property so this is going to contain the information about the authenticated client this is important because now I can use this to access the identity and get the name of this client which is actually going to match the user identifier so when a new client connects to the notifications Hub I'm just going to send them a welcome message back saying thank you for connecting the next thing I need to do is to configure my Hub with my web API so you do that by saying map Hub and you specify your Hub class so this is our notifications Hub and I also need to say which route on my API is going to be used to connect to the hub I'm just going to say notifications and this is all you need to do to expose a signalr hub from your backend now I'm going to take this a step further and add another class which is going to be a background service so let's call This Server time Notifier and I'm going to implement it using the background service which behind the scenes implements the I hosted service which is a way to implement background services with your asp.net core applications so to start out I'm going to define a few dependencies that I'm going to need so I'll Define a private static read-only time span which is going to represent how often I'm going to send the notification to my signalr clients I'm going to call it period and let's give it a value of time span from seconds and let's say every 5 seconds then and I'm going to inject an eye logger of server time Notifier and we'll call it logger let's inject this from The Constructor and I'm going to need one more service which is going to be my signalr Hub context so I need to inject the I Hub context interface and because I'm using the strongly typed Hub I also need to use the generic variant of the ihub context the first argument is my Hub type so notifications Hub and the second argument is my signalr client so this is the inertification client and let's just call it context I'm going to inject this from The Constructor and now we can use them in the execute async method to send messages to my clients so I'm going to create a periodic timer using the time span that I just defined and the timer is going to execute every five seconds so periodic timer I'm going to give it a period and here's what I can do I'm going to define a while loop and I'm going to say while stopping token is cancellation requested or rather while it's not requested and we're going to await on the timer and wait for the next deck I'm also going to pass it the cancellation token this is going to execute my Loop every 5 seconds and inside of the loop I'm going to just add an information log that I'm running the service so let's say executing and let's call it service and let's give it the die and I'm going to pass name off server time Notifier and let's grab the time in a variable so update time and I'm going to use date time now and I'm going to use that as the second argument and then I'm going to use my Hub context to send a message to my client which is going to be my blazer webassembly application so I'm going to say client and right now I'm going to send the message to all of my connected clients but later I'm going to show you how to scope this to a single user and we're just going to call the receive notification method and the content is just going to be server time equals and let's just use the date time object first because this is asynchronous I'm going to await it and we have a background service that's going to send a notification to our clients every 5 Seconds to register this background service you need to go to your program class and you need to say Builder Services add hosted service and just specify your background service and then it's going to be started when your backend application starts up I'm also going to take care of any potential course issues which stands for cross-origin resource sharing so I'm going to say add course to add the course services and I'm going to Define my course policy so I'm going to say use course and then I can Define my policy so I'll say policy allow any header allow any method and allow any origin so this will just allow any application to connect to my backend to avoid course issues of course in production you're going to configure the policy to match your specific client application so now let's move to the client-side application which is implemented using Blazer webassembly and add the signalr connection on that side I'm going to start by installing the nuget package for connecting to Signal R I'm looking for this signal our client library and I'm going to install the version that matches my current Blazer web assembly version so I'm going to use 7.0.7 and I'm going to to install this library with the signalr client installed I can go ahead and open up my home page component which is defined inside the index Razer file I'm not going to dive into Blazer fundamentals in this video but let's talk about a few pieces that are part of a Blazer component we have the route of our component at the top so we designate this component as a page with the route of just a dash so this is our home page then we have a page title element which defines the title of our page in the browser and we have our markup which just defines the content of our page now if I want to Define some code on my client side I'll do that by creating a code block and then I can Define my code inside I'm going to define a private field which is going to represent My Hub connection to this signal R Hub let's call this The Hub connection then I'm going to define a list which is also going to be read only and it's going to be a list of strings and it's going to contain my messages so let's initialize it to an empty list and I'm going to overwrite the uninitialized async method this is the method that our application will call when this component is initialized so we can add some additional steps inside like connecting to our signalr Hub so I'm going to use my Hub connection and create a new Hub connection Builder I'm going to Define my URL which is the address of my backend API and I'm just going to hard code this to the route to my singular Hub and this is the path to my API and then the path to the hub is going to match what we exposed in our Hub configuration and then I can just say build and this is going to obtain a connection to my signalr Hub I can also use the Hub to Define callbacks for my client-side methods by saying on and I can define a delegate that's going to represent the methods on my client side and we're going to give it the same name game as we did in our client interface so the method name is receive notification and then the body of this method is just an action accepting a string from the back end so I'm going to use this string to just add it to the list of messages so let's add this to the list of messages and then we need to tell Blazer to refresh the user interface so we're going to do this by saying invoke async and pass it the state has changed method in both casing is a way for me to call our client-side method and state has changed will tell my component that it needs to render some changes to the user interface and the last thing that I need to do here is to actually start my Hub connection so I'm going to say hubconnection start async so this will take care of connecting my client to this signal or Hub and we're going to start to receive messages from our backend and now let's render them from the user interface I'm going to say here messages from the server are going to live down here and let's define an unordered list which is going to contain my element and I'm going to use a for each Loop to iterate over my messages which are inside of my messages list and just render the message as a list item so list item and I can say the content of the list item is the current message in the messages list I'm also going to take care of properly disposing of the Hub connection so I'm going to implement the I async disposable interface in my component and let's implement the missing members which is just the dispose async method and what I'm going to do inside is check if the Hub connection is not now so if app connection is not null then we're just going to await hubconnection this pose async and this will take care of freeing up any resources held by the Hub connection so now let's start the application and see if our connection between the blade laser client and the asp.net core web API is working correctly so here's my client interface and you can see that we got back the thank you for connecting message from the notifications Hub which is sent when we connect to the hub and now we are receiving a message from the background job every five seconds telling us what the current server time is so the connection from the Blazer client application and our server through signalr is working however it has the disadvantage that we are sending this message as a broadcast message to all clients it's much more powerful if we are able to send a message to a specific line and I'm going to show you how to do this now I'm going to start by adding a nougat package for adding Json web token authentication so I'm going to search for JWT Bearer and I'm going to install Microsoft asp.net core authentication JWT better now let's register the required services in our program class so I'm going to say Builder services add authorization and let's also add the authentication services so add authentication I'm going to specify the authentication scheme to be JWT better defaults and use this authentication scheme and I'm also going to say add JWT bear now this takes care of registering the services with dependency injection but we also need to add the authorization middleware so I'm going to say use authorization now this only takes care of wiring up the required services and the middleware but to actually secure my signalr Hub I need to decorate it with the authorize attribute and now anyone that wants to connect to my signalr Hub will need to pass in a valid Json web token and this is how you are able to identify specific users connecting to your signalr Hub there's a nice command line utility with the.net CLI that allows you to create a Json web token for testing purposes and you need to call dotnet user jwts and then create I'm also going to specify the name argument and pass in some random good so that I can identify a user using this guide now in reality this is going to be your subclaim on a proper Json web token which is going to be your user identifier so if I execute this command it's going to create a new Json web token here is the content of this Json web token and let's inspect what we have inside of this Json web token I'm going to paste the token on the JWT website and you can see the content of the payload so you'll notice that we have our subclaim which matches the guide that I specified the audience of this token matches the URLs of your web API and one more thing that the user jwts utility does is in your backend project is going to update the app settings development Json file and add an authentication section this is going to integrate with the authentication opt questions and you'll see that it specifies the valid audiences and the valid issuer so that your Json web token is checked when somebody connects to the API and now what we need to do is to update our Hub connection on the Blazer client to include the Json web token we need to update the call to the with URL method to configure the HTTP connection options so I'm going to access the options and you'll notice that we have a property called access token provider this is how you can set an access token for your signalr client so I'm going to give it a value of a simple function that's just going to say task from result the argument is going to be a nullable string because this is what this method accepts and the value is just going to be the Json web token that we got from the command line utility in a real application you're never going to be hard coding the access token like this but you're actually going to get it from the currently authenticated user but I hope this is enough for you to understand what you need to do before I start the application I'm going to set a breakpoint in the on connected async method so that we see what is going on and I'm going to make one adjustment to the code inside of my server time Notifier background service instead of sending this message to all of my clients I'm actually going to try to access a specific client now I can either use a connection ID which I don't have or I can access the user and this is going to try to match a user by the user identifier for the value of the user ID I'm going to pass the value that I passed to my Json web token again I'm hard coding things but you would be pulling this from the user identifier that you have in your database now how Blazer accesses this user identifier is using the default user ID provider class and let's check out the implementation so what it does is accesses the claims principle on the Hub connection and get the claim with the name of name identifier and tries to get the value so this is going to match the subclaim on my Json web token and this is how signalr knows which user it should send the message to this also takes care of if a single user has multiple connections for example we connect the same client in more than one Tab and then signalr will take care of sending the message to the correct client so let's start the application and let's see what's going to happen so the application started and we hit the breakpoint in our notifications Hub you'll notice that we were able to pass the authorization otherwise we would never even hit this breakpoint so our Json web token is working correctly and you can see that we have the connection ID here but more importantly we have the value of the user's subclaim or the user's identifier in the context user identity name property so now we're going to propagate this message to our client and we're going to start receiving messages from this server so here's what we are getting from the server you can see that the user identifier is properly sent from our signalr Hub to the client we are receiving messages and our authentication is working if we did not specify an access token then we would get an 401 unauthorized error and I also have the same application open in two more tabs so you'll see if I switch tabs that they are all receiving messages from the server and this is because they are connected using the user identifier signalr is able to Route the message to multiple connected clients based on the user identifier so if I refresh this you'll see that they are successfully receiving messages from the server if you want to learn more about signalr fundamentals take a look at this video here and make sure to smash the like And subscribe buttons on your way out and until next time stay awesome
Info
Channel: Milan Jovanović
Views: 20,726
Rating: undefined out of 5
Keywords: blazor, blazor tutorial, blazor c#, blazor webassembly, blazor server, blazor webassembly tutorial, blazor tutorial c#, blazor vs react, blazor signalr, blazor .net, blazor real-time, blazor signalr real-time, blazor notifications, blazor real-time messaging, blazor notifications system, blazor signalr hub, blazor signalr tutorial, blazor signalr c#, signalr, signalr tutorial, signalr notifications, signalr real-time notifications, signalr blazor, signalr blazor tutorial
Id: O7oaxFgNuYo
Channel Id: undefined
Length: 19min 42sec (1182 seconds)
Published: Tue Sep 19 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.