在 .NET Core 3.1 控制台中托管 SignalR Hub

Host a SignalR Hub in a .NET Core 3.1 Console

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

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

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

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

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

提前致谢!

我正在尝试更详细地解释我的问题,希望有人知道如何解决该问题。 据我了解,Microsoft 建议使用 Host.CreateDefaultBuilder 而不是 WebHost.CreateDefaultBuilder。 Host.CreateDefaultBuilder 从 json 文件中读取配置。问题是我不明白如何将调用 services.AddSignalR() 连接到我的集线器。

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

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

并且集线器被引用

ConnectionManager.GetHubContext<C_IOHub>()

集线器定义

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

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

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

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

我需要以下信息

  1. 如何在 .NET Core 中创建独立的 Hub?

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

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

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

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

  • 启动时,配置方法:
app.UseEndpoints(endpoints =>
{
    endpoints.MapHub<YourHub>(this.azureConfiguration.SignalR.Endpoint)
});
  • 关于配置服务方法:
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 将其注入到控制器、工作器等中...例如:

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

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

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

这就是我所做的,它适用于 .net core 3.1 控制台应用程序。 打开您的 .csproj 并向其中添加以下内容:

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

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

Microsoft.AspNetCore.SignalR

这是我的基本款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>();
    }
}

和基本的 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");
            });
        }
    }
}

简单多了,我希望对你有帮助:)