在 .NET Core 3.1 控制台中托管 SignalR 集线器

Host a SignalR Hub in a .NET Core 3.1 Console

我将一个由 exe 托管的旧 .NET 库从 .NET Framework 4.6 迁移到 .NET Core 3.1。程序集的一部分基于这样实现的独立 SignalR 集线器。

1
2
3
4
//-----------------------------------
// Startup SignalR Server
//-----------------------------------
m_oSignalRServer = WebApp.Start( C_AppSettings.ServerURL );

我知道必须使用 IHostBuilderHost.CreateDefaultBuilder 启动主机,但我真的不明白如何配置它。特别是,如何指定绑定和集线器名称。

欢迎提供示例代码或书籍。

docs.microsoft.com

1
2
3
4
5
6
7
8
9
public static IHostBuilder CreateHostBuilder( string [ ] args ) =>
Host.CreateDefaultBuilder( args ).ConfigureServices( ( hostContext, services ) =>
{
    services.AddSignalR( ( hubOptions =>
    {
        hubOptions.EnableDetailedErrors = true;
        hubOptions.KeepAliveInterval = TimeSpan.FromMinutes( 1 );
    } ));
} );

提前致谢!


这就是我所做的,它对我来说很好用 .net core 3.1 控制台应用程序。
打开您的 .csproj 并将以下内容添加到其中:

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

然后通过nuget包管理器添加以下包:

1
Microsoft.AspNetCore.SignalR

这是我的基本程序.cs:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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>();
    }
}

和一个基本的 Startup.cs:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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");
            });
        }
    }
}

更简单的imo希望它有帮助:)


我试图更详细地解释我的问题,并希望有人知道如何解决这个问题。
据我所知,微软建议使用 Host.CreateDefaultBuilder 而不是 WebHost.CreateDefaultBuilder 。 Host.CreateDefaultBuilder 从 json 文件中读取配置。问题是我不明白如何将呼叫 services.AddSignalR() 连接到我的集线器。

在我的旧 .NET 4.5 版本中,从我的angular来看它更容易。
服务器是用这个代码启动的

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

并且集线器是用

引用的

1
ConnectionManager.GetHubContext<C_IOHub>()

集线器定义

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

但是使用 .NET Core 我不知道如何将其构建为独立服务器。我找到的所有示例都描述了如何将 Hub 附加到现有的 MVC 项目。
我有一个带有以下代码的 Startup.cs:

1
2
3
4
5
6
7
8
9
10
11
public static void Main( string [ ] args )
{
    CreateHostBuilder( args ).Build().Run();
}

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

我需要以下信息

  • 如何在 .NET Core 中创建独立的集线器?

  • 如何获取对 Hub 上下文的引用?


  • 按照完整示例在 .NET Core 3.1 应用程序中创建和使用集线器:

    • 首先从 appsettings.json 读取配置
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    "Azure": {
       "SignalR": {
         "ClientTimeoutInterval": 3600,
         "HandshakeTimeout": 30,
         "KeepAliveInterval": 15,
         "EnableDetailedErrors": true,
         "MaximumReceiveMessageSize": 32000,
         "StreamBufferCapacity": 10,
         "SupportedProtocols": ["WebSockets","ServerSentEvents" ],
         "ServerConnectionCount": 1
        }
    }
    • 然后在启动时读取配置
    1
    private AzureConfiguration azureConfiguration;
    • 添加到配置方法
    1
    services.Configure<AzureConfiguration>(this.Configuration.GetSection(Azure)).AddOptionsSnapshot<Azure>();

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

    • 在启动时,配置方法:
    1
    2
    3
    4
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapHub<YourHub>(this.azureConfiguration.SignalR.Endpoint)
    });
    • 在配置服务方法上:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    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;
    });

    所以您在启动时的配置已完成,现在只需创建您的集线器即可。
    创建集线器后,您可以使用 DI 将其注入到控制器、工作器等中...例如:

    1
    2
    3
    4
    5
    6
    7
    private IHubContext<YourHub, IYourHub> YourHub
    {
        get
        {
            return this.serviceProvider.GetRequiredService<IHubContext<YourHub, IYourHub>>();
        }
    }

    PS:您应该在添加集线器方法之前配置您的 CORS

    1
    2
    3
    4
    5
    6
    7
    8
    services.AddCors(options =>
    {
        options.AddPolicy(CorsPolicy, builder => builder.WithOrigins("http://localhost:4200")
            .AllowAnyHeader()
            .AllowAnyMethod()
            .AllowCredentials()
            .SetIsOriginAllowed((host) => true));
    });