Stefan S
Stefan S

Reputation: 33

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!

Upvotes: 1

Views: 6981

Answers (3)

Jacqueline Loriault
Jacqueline Loriault

Reputation: 700

this is what I do and it works fine for me with a .net core 3.1 console app. open up your .csproj and add the following to it:

<ItemGroup>
    <FrameworkReference Include="Microsoft.aspNetCore.App" />
</ItemGroup>

then add the following package via nuget package manager:

Microsoft.AspNetCore.SignalR

this is my basic program.cs:

using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;

namespace GameServer
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            CreateWebHostBuilder(args).Build().Run();
        }

        private static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args).UseStartup<Startup>();
    }
}

and a basic Startup.cs:

using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace GameServer
{
    public class Startup
    {
        public IConfiguration Configuration { get; }

        public Startup(IConfiguration configuration) { Configuration = configuration; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSignalR();
        }

        public void Configure(IApplicationBuilder app)
        {
            app.UseRouting();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapHub<ChatHub>("/chat");
            });
        }
    }
}

a lot simpler imo hope it helps :)

Upvotes: 3

Kiril1512
Kiril1512

Reputation: 3611

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));
});

Upvotes: 0

Stefan S
Stefan S

Reputation: 33

I trying to explain my problem in more details and hope someone know how to solve the issue. Microsoft recommend to use Host.CreateDefaultBuilder instead of WebHost.CreateDefaultBuilder as I have understood. Host.CreateDefaultBuilder reads configuration from json files. The problem is that I don't understand how to connect the call services.AddSignalR() to my Hub.

In my old .NET 4.5 version it was easier from my point of view. The server was started with this code

IDisposable oSignalRServer = WebApp.Start( "http://localhost:3211" );

And the hub was referenced with

ConnectionManager.GetHubContext<C_IOHub>()

Hub definition

[HubName( "IOHub" )]
public class C_IOHub : Hub

But with .NET Core I'm lost how to build this as a standalone server. All examples I have found describe how to attach the Hub to an existing MVC project. I have a Startup.cs with the following code:

public static void Main( string [ ] args )
{
    CreateHostBuilder( args ).Build().Run();
}

public static IHostBuilder CreateHostBuilder( string [ ] args ) =>
Host.CreateDefaultBuilder( args )
.ConfigureServices( ( hostContext, services ) =>
{
    services.AddSignalR();
} );

I need the following information

  1. How do I create a standalone Hub in .NET Core?

  2. How do I obtain a reference to the Hub context?

Upvotes: 1

Related Questions