AspNetCore + Angular + SignalR + Typescript = Drinking Game

Getting realtime data from the server to the client has become easier than ever. I wrote a post about a year ago with steps on how to setup SignalR with AspNetCore and then make it work with Angular. But the bandaid I put together at the time looked terrible (using jQuery inside Angular). With the .net Core team working as hard as they are, I'm now able to show you a much cleaner solution.

The source code covered in this post is here

Here are the steps I took in the video:

  • Create a new dotnet core with Angular using the SPA templates with the command dotnet new angular. For more information about the SPA templates, check out this link
  • Add a new NPM source to bring the preview version of SignalR for your client application
    • You can achieve that by creating a .npmrc file in your project folder and adding a single line in there @aspnet:registry=https://dotnet.myget.org/f/aspnetcore-dev/npm/. Then in your console npm i @aspnet/signalr --save
  • Add a new Nuget package source to brin the preview version of SignalR for your dotnet application
    • You can achieve that by creating a Nuget.config file in your project folder and adding the code below then in your terminal dotnet add package Microsoft.AspNetCore.SignalR -v 1.0.0-preview2-30187, make sure the verion of the nuget package lines up with the npm package
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <add key="AspNetCore" value="https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json" protocolVersion="3" />
  </packageSources>
</configuration>
  • Now create a hub
public class EchoHub : Hub
{
    //you're going to invoke this method from the client app
    public void Echo(string message)
    {
        //you're going to configure your client app to listen for this
        Clients.All.SendAsync("Send", message);
    }
}
  • Wire it up in your startup.cs
public void ConfigureServices(IServiceCollection services)
{
    /*...*/
    services.AddSignalR();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    /*...*/
    app.UseSignalR(s => s.MapHub<EchoHub>("/echo"));
}
  • Now it's time to configure your client app
import { Component, OnInit } from '@angular/core';
import { HubConnection } from '@aspnet/signalr';

@Component({
    selector: 'home',
    templateUrl: './home.component.html'
})
export class HomeComponent implements OnInit {
    public message: string = '';
    public messages: string[] = [];
    public hubConnection: HubConnection;
    ngOnInit() {
        //this lines up with the hub mapped in the startup
        this.hubConnection = new HubConnection("/echo");
        
        //this lines up with the method called by `SendAsync`
        this.hubConnection.on("Send", (msg) => {
            this.messages.push(msg);
        });
        
        //this will start the long polling connection
        this.hubConnection.start()
            .then(() => { console.log("Connection started"); })
            .catch(err => { console.error(err); });
    }

    echo() {
        //this will call the method in the EchoHub
        this.hubConnection.invoke("Echo", this.message);
    }
}

It's hard to be easier than this.

Hope it helps.

Cheers