Search code examples
asp.net-coreconsolesignalrhostingself-hosting

Host a SignalR Hub in a .NET Core 3.1 Console


I migrating an old .NET library hosted by an exe from .NET Framework 4.6 to .NET Core 3.1. A part of the assembly is based on a stand alone SignalR hub implemented like this.

//-----------------------------------
// Startup SignalR Server
//-----------------------------------
m_oSignalRServer = WebApp.Start( C_AppSettings.ServerURL );

I understood that the host must be initiated with IHostBuilder and Host.CreateDefaultBuilder but I really don understand how to configure it. And especially, how to I specify the bindings and hub names.

Sample code or books are welcome.

learn.microsoft.com

public static IHostBuilder CreateHostBuilder( string [ ] args ) =>
Host.CreateDefaultBuilder( args ).ConfigureServices( ( hostContext, services ) =>
{
    services.AddSignalR( ( hubOptions =>
    {
        hubOptions.EnableDetailedErrors = true;
        hubOptions.KeepAliveInterval = TimeSpan.FromMinutes( 1 );
    } ));
} );

Thanks in advance!


Solution

  • Follows a full example to create and use a hub in the .NET Core 3.1 app:

    • First read the configuration from appsettings.json
    "Azure": {
        "SignalR": {
          "ClientTimeoutInterval": 3600,
          "HandshakeTimeout": 30,
          "KeepAliveInterval": 15,
          "EnableDetailedErrors": true,
          "MaximumReceiveMessageSize": 32000,
          "StreamBufferCapacity": 10,
          "SupportedProtocols": [ "WebSockets", "ServerSentEvents" ],
          "ServerConnectionCount": 1
        }
    }
    
    • Then read the configuration on the startup
    private AzureConfiguration azureConfiguration;
    
    • Add in to configuration method
    services.Configure<AzureConfiguration>(this.Configuration.GetSection(Azure)).AddOptionsSnapshot<Azure>();
    

    Note: you can resolve the configuration like this this.azureConfiguration = provider.GetRequiredService<AzureConfiguration>();.

    • On the startup, configure method:
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapHub<YourHub>(this.azureConfiguration.SignalR.Endpoint)
    });
    
    • On the configure services method:
    services.AddSignalR(hubOptions =>
    {
        hubOptions.ClientTimeoutInterval = TimeSpan.FromSeconds(this.azureConfiguration.SignalR.ClientTimeoutInterval);
        hubOptions.HandshakeTimeout = TimeSpan.FromSeconds(this.azureConfiguration.SignalR.HandshakeTimeout);
        hubOptions.KeepAliveInterval = TimeSpan.FromSeconds(this.azureConfiguration.SignalR.KeepAliveInterval);
        hubOptions.EnableDetailedErrors = this.azureConfiguration.SignalR.EnableDetailedErrors;
        hubOptions.MaximumReceiveMessageSize = this.azureConfiguration.SignalR.MaximumReceiveMessageSize;
        hubOptions.StreamBufferCapacity = this.azureConfiguration.SignalR.StreamBufferCapacity;
    });
    

    So your configuration on the startup is done, now just go create your hub. After the hub is created, you can inject it using DI in to the controllers, workers, etc... like:

    private IHubContext<YourHub, IYourHub> YourHub
    {
        get
        {
            return this.serviceProvider.GetRequiredService<IHubContext<YourHub, IYourHub>>();
        }
    }
    

    PS: You should configure your CORS before adding the hub methods.

    services.AddCors(options =>
    {
        options.AddPolicy(CorsPolicy, builder => builder.WithOrigins("http://localhost:4200")
            .AllowAnyHeader()
            .AllowAnyMethod()
            .AllowCredentials()
            .SetIsOriginAllowed((host) => true));
    });