Providing real time information to your Javascript apps with ASP.NET Core SignalR. With ASP.NET Core and SignalR you can add real time functionality with ease and keep your application up to date without letting the clients reloading their page manually.
Instructor: [00:00] Let us start with the folder [00:02] structure having a separate [00:03] client and server folder. In the [00:05] server folder, we will create a [00:07] new Web API with the dotnet CLI [00:09] anti command dotnet new webapi. [00:13] Having done that, let's head [00:15] over to Startup.cs file. For [00:17] accepting requests from a [00:19] different origin than the one [00:20] our server is running on, we [00:22] have to add CORS to the pipeline [00:24] and of course SignalR as we want [00:26] to use that as well. [00:28] The [00:28] extension method at SignalR is [00:30] built-in and we can simply add [00:32] it to a ServiceCollection to use [00:34] SignalR. To configure CORS, we [00:37] have to add a policy which we [00:39] will name MyAllowSpecificOrigins, [00:42] and configure this policy into [00:44] ServiceCollection as well inside [00:46] the ConfigureServices method. [00:48] First, let us use CORS. For the [00:50] sake of simplicity of this demo, [00:52] we will allow any header, the [00:54] origin. We run the client later [00:55] on, allowing credentials and any [00:58] method. Please do not use that [01:01] one in production, as it is [01:02] really open. However, we have to [01:05] add CORS to the middleware as [01:06] well, in the configure method [01:07] with app.UseCors, passing it the [01:10] name of the policy. [01:12] We have to [01:12] enable a route for SignalR as [01:14] well, which we will do with the [01:16] endpoint routing underneath. We [01:18] can map a route, messages, to [01:20] the not-yet existing Messages [01:22] Hub, with the MapHub method from [01:24] the endpoints. This route can [01:26] get called from the client to a [01:27] class which represents the [01:29] interface, which can get invoked [01:30] from the client-side's [01:32] JavaScript. These classes are [01:34] called Hubs. [01:36] Let's create this [01:37] message Hub next. Therefore, we [01:40] create a folder called Hubs and [01:42] add a class, Message, up in here. [01:46] This is a normal C# class which [01:48] inherits from the Hub class from [01:49] the SignalR namespace. Inside [01:52] that, we can place a method [01:54] called SendMessage, which takes [01:56] a string parameter called chat- [01:58] message, and then broadcasts [01:59] this message to all connected [02:01] clients. [02:02] We take SendBack as [02:04] event name, and pass the given [02:05] message as parameter. Let's our [02:09] startup class know about this [02:11] message Hub and head over to our [02:13] client, where we find three JS [02:14] files and one HTML file. The [02:17] SignalR file comes from the [02:19] signalr npm package directly. [02:21] You can also download it from [02:22] GitHub. I just copied it here. [02:25] You can find the links in the [02:26] description of this video. [02:28] As [02:28] SignalR does not need JQuery [02:30] anymore to work, we only have [02:32] JQuery in here to make access to [02:34] the DOM elements easier. [02:36] Otherwise, we would not need it [02:37] for using SignalR. [02:39] The index. [02:40] html is the file which provides [02:42] an input. We can type text in, a [02:45] button to fire a request, and an [02:47] unordered list to apply items to. [02:49] The file chat.js should contain [02:51] a logic, so let's start there. [02:53] First, we define the URLs. As [02:56] our server is running on [02:57] localhost:5001, we also have to [02:59] define the SignalR route we [03:01] mapped in the style of .cs, as [03:03] this is URL/Messages. Then we [03:07] can establish the SignalR [03:09] connection. Let us new this up [03:11] to make it correct, and register [03:13] on an event we send from the [03:14] server called SendBack. This is [03:17] the identifier we gave in the [03:18] Hub method. [03:20] The second [03:20] parameter is a fat arrow [03:22] function which takes the given [03:23] parameter, so we just append it [03:25] to our HTML list. After that, we [03:28] can start the connection. This [03:30] returns a promise, and we can [03:31] log out the success. [03:33] Finally, [03:34] we have to add a click event [03:35] handler to our button, which [03:37] will call invoke on our SignalR [03:39] connection to that given route, [03:41] which is mapped to the Hub we [03:43] just created. First parameter is [03:45] the method we want to invoke, [03:47] the second parameter is the [03:48] parameter we want to pass. At [03:50] the end, we reset the input. [03:53] That's it. [03:54] Let's start a server [03:55] and client via console and see [03:57] that in the browser. I opened up [03:59] two different browsers to see [04:01] the message going around. On the [04:03] right-hand side in the console, [04:04] we can see that the connection [04:05] was established. We can now type [04:07] something in the box and send it. [04:10] With the click on the button, [04:11] the JavaScript invokes the [04:12] method on the SignalR connection, [04:14] calls the Hub and broadcasts the [04:16] message to all connected clients. [04:18] We do catch the event and append [04:20] the send message at the list. [04:22] Fine, that works. How about the [04:25] server-invoken actions on a [04:26] normal PUT, POST, PATCH, or [04:28] DELETE request? We can also [04:30] handle that. Let's take a look [04:32] at our controller. There, we can [04:34] fire requests too. First, we can [04:37] inject the HubContext to the [04:39] constructor, because we added [04:40] SignalR to our services in the [04:42] startup file. [04:44] We can inject a [04:45] generic interface, IHubContext, [04:47] into our controller, with our [04:48] Hub getting passed as a type. [04:51] Let's add a new POST method [04:52] which will use the HubContext in [04:54] the method, and send an event [04:55] called ItemReceived. We're just [04:58] passing the value we get given [05:00] in the request body for the sake [05:02] of simplicity. [05:04] Let us prefix [05:05] the controller route to API to [05:08] be more precise, and head to our [05:09] client files. Here, we first add [05:14] the URLs and register to the [05:16] event the server sends us now, [05:18] ItemReceived. We are appending [05:20] the item to the list again, but [05:21] this time with a fromServerPost [05:24] prefix. [05:25] Then we head over to [05:26] our HTML and add a new button, [05:28] and just call it server-invoke, [05:30] with an id, post-message, and [05:32] add a click handler to it, which [05:34] just posts a hard-coded string, [05:36] Hello, to the backend. [05:39] Let's [05:39] start the browser again and [05:40] click the old button first. This [05:44] works. Now the new button. This [05:47] works as well. This is how you [05:48] can call Hub methods from [05:50] JavaScript, react to them, and [05:52] also react to events the server [05:54] sends over in normal HTTP [05:56] requests. All this with ASP.NET [05:58] Core and SignalR.