DEV Community

John Peters
John Peters

Posted on • Updated on

SignalR / WebSocket Concepts : in ASP.NET Core 3.1

The WebSocket is its own Layer 7 protocol.

It's not the HTTP protocol (also running in Layer 7) but it seems to be able to share port 80 and 443 with HTTP.

SignalR

A 'helper' library for WebSockets. The SignalR library introduced the "hub" concept. This allows both the server and client to call each other's methods.

You mean my server can invoke a method in my Typescript client and my Angular code can call a server method directly? Yes...

So what's so helpful with SignalR?

Similar to the DOM object where context is everything, SignalR provides contextual access to properties of the connection.

We have access to the SignalR wrappers' properties, such as user, userid, features, as well as its commands.

Clients can call methods on all connected clients, a single client, or specific client groups.

Sounds like an instant chat application doesn't it? Or perhaps a legitimate heartbeat application?

Everything is async by default with strong type support. Events are built-in as is Error Handling.

Note: The Web Socket architecture is similar to FTP (full duplex). In FTP there are two ports; one is the command channel, the other is the data channel. Commands can be sent asynchronously with respect to the data flow. FTP is completely interrupt-able and has full-duplex ability.

Security

CORS must be enabled for the Web Site Port. These are the configurations necessary in startup.cs.

  // In method ConfigureServices
  // Only allow port 4200 to 'bypass' CORS
    services.AddCors(options =>
    {
        options.AddPolicy("CorsPolicy",
            builder => builder.WithOrigins("http://localhost:4200")
            .AllowAnyMethod()
            .AllowAnyHeader()
            .AllowCredentials());
    });
// And the 'strongly typed' endpoint added 
// In method Configure 
   app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
        // This makes the HUB fly
        endpoints.MapHub<AHubClass>("/hub");  
    });    

Enter fullscreen mode Exit fullscreen mode

Angular Client

The SignalR Typescript counterpart starts as a service.

It imports the @aspnet/signalar library and will define a signalr.HubConnection. This hubconnection is configured via a HubConnectionBuilder which will identify the url to connect.

The connection is then started which allows for adding eventhandlers. The handler names must match the server-side SendAsync's first string parameter which is the key of that message.

import { Injectable } from '@angular/core';
import * as signalR from "@aspnet/signalr";
import { MyModel } from '../_interfaces/mymodel.model';

@Injectable({
  providedIn: 'root'
})
export class SignalRService {
  public data: MyModel[];

private hubConnection: signalR.HubConnection

  public startConnection = () => {
    this.hubConnection = 
    new 
 signalR.HubConnectionBuilder() 
// This url must point to your back-end hub                        
.withUrl('https://localhost:8081/hub') 
.build();

    this.hubConnection
      .start()
      .then(() => console.log('Connection started'))
      .catch(err => console.log('Error while starting connection: ' + err))
  }

  public addDataListener = () => {
    this.hubConnection.on('specificMessageName', (data) => {
      this.data = data;
      console.log(data);
    });
  }
}
Enter fullscreen mode Exit fullscreen mode

Summary
For those that use Signalr the name is synonymous with WebSockets. Signalr merely makes it easier to establish Websocket connections, and introduces the HUB type in C# and Typescript. This is great for intellisense and discovering the API...

References
ASP.Net Core WebSocket support
ASP.NET SignalR
SignalR Hubs
Remote Procedure Calls
CodeMaze SignalR Chart

Interview Answers
How would you create a chat client? Answer: I use ASP.NET Core's SignalR Websocket library. It allows for a centralized hub, and all connected clients to send messages back and forth. It also allows the server to control all connections as well as to message each client's functions!

Oldest comments (0)