Umbraco ships with signalR installed, find out how to add your own hub(s) to the existing setup
Umbraco ships with signalR installed. This article shows how to add your own hub(s) to the existing setup.
Create a hub and its interface
We are going to go for the most basic implementation possible, a status ping. So first create a new interface with the following code:
publicinterfaceITestHubEvents{ // Define the events the clients can listen topublicTaskPong();}
And then the actual hub:
usingMicrosoft.AspNetCore.SignalR;publicclassTestHub:Hub<ITestHubEvents>{ // when a client sends us a pingpublicasyncTaskPing() { // we trigger the pong event on all clientsawaitClients.All.Pong(); }}
Define a custom route
Next up, is defining a custom route. For this, we are going to use a IAreaRoutes and the base umbrace backend path so we dont have to reserve another path in the settings.
Last step in the setup is registering our custom route:
usingMicrosoft.AspNetCore.Builder;usingMicrosoft.Extensions.DependencyInjection;usingUmbraco.Cms.Core.Composing;usingUmbraco.Cms.Core.DependencyInjection;usingUmbraco.Cms.Web.Common.ApplicationBuilder;usingUmbraco.Extensions;publicclassTestHubComposer:IComposer{publicvoidCompose(IUmbracoBuilder builder) { // first we are going to add signalR to the serviceCollection if no hubs have been added yet // this is just in case Umbraco ever decides to use a different technologyif (!builder.Services.Any(x =>x.ServiceType==typeof(IHubContext<>))) {builder.Services.AddSignalR(); } // next is adding the routes we defined earlierbuilder.Services.AddUnique<TestHubRoutes>();builder.Services.Configure<UmbracoPipelineOptions>(options => {options.AddFilter(newUmbracoPipelineFilter("test", endpoints: applicationBuilder => {applicationBuilder.UseEndpoints(e => {var hubRoutes =applicationBuilder.ApplicationServices.GetRequiredService<TestHubRoutes>();hubRoutes.CreateRoutes(e); }); } )); }); }}
Add the route in appsettings.json file
When setting up SignalR routes, add the route to ReservedPaths in the appsettings.json file like:
You need to provide the default reserved paths, else you'll run into an issue as mentioned on GitHub.
Test the setup
And lastly we can test the setup with some JavaScript in our view:
<!-- We reference the signalR js file that comes with Umbraco --><scripttype="text/javascript"src="/umbraco/lib/signalr/signalr.min.js"></script><script>var connection =newsignalR.HubConnectionBuilder() .withUrl("/umbraco/testhub") // this is the url that we created in the routing `TestHubRoutes.GetTestHubRoute()`
.withAutomaticReconnect().configureLogging(signalR.LogLevel.Warning).build();// register our callbacks when the hub sends us an eventconnection.on("Pong",function () {console.log("Pong"); });// start the connectionconnection.start().then(function () {console.info("signalR connection established");// connection is established => call a function on the hubconnection.invoke("Ping").catch(function (err) {returnconsole.error("Could not invoke method [Ping] on signalR connection",err.toString()); }); }).catch(function (err) {returnconsole.error("could not establish a signalR connection",err.toString()); });</script>
When you insert this in a view, you should see a signalR connection established console message followed by Pong.