SignalR with Aspnet core 2.2 and angular6
The SignalR server library is included in the
Microsoft.AspNetCore.App.
Next we need to configure our wepapi to use it.
in configureservices() section add
services.AddCors();
in the configure method add
.AllowAnyHeader()
.AllowAnyMethod()
.SetIsOriginAllowed((host) => true)
.AllowCredentials()
);
this is different from core 2.1 as allowanyorigin is not supported with allowcredentials. So we need to either specify which origins to allow for eg:
app.UseCors(builder =>
{
builder.WithOrigins("http://localhost:4200")
.AllowAnyHeader().AllowAnyMethod().AllowCredentials();
});
or we can use
.SetIsOriginAllowed((host) => true)
Next is to create a Hub.
public class MessageHub: Hub
{
}
My Hub class doesnt contain anything. We need to inherit from the Hub class which will give it some special properties to call the client side functions from the server.
In my WebApi I have created a very simple endpoint that returns a random name from a predefined list. This name will be sent to the angular app which will display it on the server. So the server code looks something like this.
I have created a controller called Home that has an action named GetRandomNames() that returns a random name.
create an instance of the hub through dependency as follows.
private readonly IHubContext<MessageHub> _hub;
public HomeController(IHubContext<MessageHub> hub)
{
_hub = hub;
}
we can call the client side function called "addNewItem" through this _hub property.
this._hub.Clients.All.SendAsync("addNewItem",name);
this will send the random name to all connected clients. The hub property has several other methods through which we can send data to selected or even a single client also.
Once we run visual studio we will get the URL from which we can access the API. In my case its https://localhost:44330/.
Client Side Configuration
Used VsCode for the client side part, also to demonstrate how to use CORS.
create an angular app using the angular cli
ng new sample SignalrSample
once project is created run
npm install
appcomponent.html
<!--The content below is only a placeholder and can be replaced.-->
<div style="text-align:center">
<h1>
Welcome to {{ title }}!
</h1>
<img width="300" alt="Angular Logo" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg==">
</div>
<h2>Here are some links to help you start: </h2>
<ul class="heroes">
<li *ngFor="let emp of empList">
<span class="badge">{{ emp }}</span>
</li>
</ul>
<div>
<input type="button" value="add new" (click)="getNewName()">
</div>
appcomponent.ts
import { Component, OnInit } from '@angular/core';
import {HubConnection, HubConnectionBuilder } from '@aspnet/signalr';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'signalr sample using aspnet core 2.2 and angular 6';
empList:string[]=["papa","mummy"];
constructor(private http: HttpClient) { }
ngOnInit(): void {
var connection =new HubConnectionBuilder().withUrl("https://localhost:44330/messageHub").build();
connection.on("addNewItem",data=>{
this.empList.push(data);
});
connection.start().then(()=>alert("Connected to server.."))
// connection.start()
// .then(()=>connection.invoke("connected","connected to WebApi"))
// .catch(function (err) {
// return console.error(err.toString());
// });
}
getNewName():void{
this.http.get("https://localhost:44330/home/GetRandomNames").subscribe(function(result){
})
}
}
appmodule.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule
],
providers: [HttpClientModule],
bootstrap: [AppComponent]
})
export class AppModule { }
Now run the API and use the below command to start the angular app
ng serve
Need to be in the directory where the package.json resides for ng-serve to work
open localhost:4200 on different tabs and click the button
the new name will be seen on each browser
Comments
Post a Comment