Send instant message from server back to client using SignalR

This is a small blogpost explaining how to use SignalR for ASP Core 2.1 to send a message (or a signal 🙂 ) from the server (controller action) back to the client view. Alot of posts explains how to make various bidirectional chats using SignalR to send messages from client to the server (from view to controller and back again), but the other way around (from server to client) is useful if you want to show progress bars or start a long running task while continually report to the user how it’s going.

Using MVC or Razor Pages can be somewhat linear: User submits something -> a controller action behind the scene handles the input and executes something (ex. a remote runbook) -> when all is done the result is returned to the user (the view). But if you want to report back to the user in-between (before returning) like sending a message to the user that the remote runbook actually started (200 OK) then it’s not possible due to the linearity of the Model-View-Controller flow. Now a simple OK result could be handled by an AJAX call, but then you might be forced to mix javascript clients and C# SDK clients and what if they need to share stuff with each other, it could easily get messy. Personally if I can avoid javascript I usually do that (atleast avoid making business logic, handle page layout etc. is another thing) – signalR to the rescue 🙂

For a more in-depth explanation you can check out this blogpost here. The following is the quick version for ASP.NET Core 2.1 and could be seen as a minified version (cheatsheet?) to get you up and running fast

Initial setup:

Setup is more or less taken from the official Microsoft documentation here

Create a new web app if you don’t have one already

Create folder called Hub (folder is optional) and a new class file in that folder, in this example I have called mine MyHub.cs

This class needs to derive from the Hub class and is just empty for now since we don’t need to call any methods from client, only from server:

You can read documentation here on different methods to implement in this class

In startup.cs:

Javascript setup

Install SignalR client library by opening Package Manager Console in Visual Studio and run the following commands:

You might get some lock errors, but there will be a signalr.js file located here: <NameOfYourProject>\node_modules\@aspnet\signalr\dist\browser\signalr.js

Create a signalr folder at : wwwroot\lib\ within your project and place the file there:

Add client side listener method:

Create a custom javascriptfile at wwwroot\js\ called anything you want, mine is called signal.js (very generic I know, could also be called progressBar.js to state the intention of what you are doing)

Add the following:

The first part is making the connection and starting it, the second method is the listener to which we can send messages to from the server instantly!

Check out the documentation here for more options available from the client-side

Javascript references

So now we just need to refer our two javascript files signalr.js and <customfile>.js.

In your view, ex. index.cshtml, paste in the following at the end:

First the library and second your custom file

Server side communication

The fun part! In your Controller action we can now directly and instantly communicate with the client and send messages to this javascript connection we just made called initSignal. You would probably put the logic for this elsewhere (like a repository), but for now we are just going to place it directly in the post action method after the user have pressed Submit:

 

Result after pressing submit:

There you go 🙂

Notice that when we redirect the page will refresh and the console message disappear since it’s only temporary until the view returns, but the paragraph message will remain unless you replace it with a message when the view returns. Because of this we can make progress bars (actual progress bars, not just a random spinning gif :D) or we could show status messages to the user while a task is running etc. You could argue that the message goes to all clients and not just the particular client which might not be what you want, but there are other methods to use here which requires a new blogpost to cover, roughly you could pass the client connectionId to your post method and then only send to that. Example: myHubContext.Clients.Client(connId).SendAsync(“initSignal”,”message to connection with Id: ” + connId);

Hope this was helpful to get you started with SignalR at least. There are alot of posts out there to cover more complex scenarios.

Cheers

Morten

 

 

 

 

By | 2018-08-09T12:51:06+00:00 August 9th, 2018|Scripting & Development|0 Comments

About the Author:

Morten Meisler
Consultant / Developer / Trainer Key areas / products: System Center Service Manager System Center Operations Manager Automation (System Center Orchestrator / Service Management Automation (SMA)) Development: C#.Net, Powershell, SQL, Web development / HTML5 (Javascript,jQuery,CSS,HTML, Wordpress etc.)

Leave A Comment