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 consolenpm i @aspnet/signalr --save
- You can achieve that by creating a
- 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 terminaldotnet 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
- You can achieve that by creating a
<?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