【问题标题】:Host a SignalR Hub in a .NET Core 3.1 Console在 .NET Core 3.1 控制台中托管 SignalR 集线器
【发布时间】:2020-02-26 20:57:47
【问题描述】:

我将由 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 );
    } ));
} );

提前致谢!

【问题讨论】:

  • 你好。我不明白你在你的问题中真正问的是什么。您想创建一个通用库来使用 SignalR,并传递自定义配置?
  • 嗨。该代码位于 lib 中,因为它将从控制台应用程序或 Windows 服务中执行。我不明白如何连接集线器。使用 asp.net 似乎要容易得多: app.UseEndpoints(endpoints => { endpoints.MapHub("/chathub"); });
  • 不,该文档描述了用于常规 .NET 的 SignalR。我正在开发 .NET Core。

标签: asp.net-core console signalr hosting self-hosting


【解决方案1】:

我试图更详细地解释我的问题,并希望有人知道如何解决这个问题。 据我所知,微软建议使用 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 上下文的引用?

【讨论】:

    【解决方案2】:

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

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

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

    Microsoft.AspNetCore.SignalR
    

    这是我的基本程序.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");
                });
            }
        }
    }
    

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

    【讨论】:

      【解决方案3】:

      按照完整示例在 .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>();
      

      注意:你可以像this.azureConfiguration = provider.GetRequiredService&lt;AzureConfiguration&gt;();这样解析配置。

      • 启动时,配置方法:
      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));
      });
      

      【讨论】:

      • 感谢您的详细回答,但我仍在为访问 app.UseEndpoints 而苦苦挣扎。我知道将 SDK 从 Microsoft.NET.Sdk 更改为 Microsoft.NET.Sdk.web 是可能的,但这是不可能的,因为它在一个库中。
      • 你可以简单地使用app.UseSignalR(routes =&gt; { routes.MapHub&lt;YourHub&gt;(this.azureConfiguration.SignalR.Endpoint); });
      • 我只是认为我需要将 SDK 更改为 Microsoft.NET.Sdk 才能访问 MapHub。我不知道控制台和 asp.net Web 应用程序之间的细微差别。谢谢大家的帮助!
      猜你喜欢
      • 1970-01-01
      • 2020-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-16
      • 2013-05-07
      • 2023-03-29
      相关资源
      最近更新 更多