让 SignalR IConnectionManager GetHubContext 在 Startup.cs 在 aspnet 核心中工作

Getting SignalR IConnectionManager GetHubContext working in Startup.cs in aspnet core

我似乎无法使用以下代码。我所做的只是在 ConfigureServies 中调用 _serviceProvider.GetService<IConnectionManager>(); 并将其保存在静态字段中,稍后尝试使用它来访问 IConnectionManager 并随后调用 GetHubContext<MyHub> 所以我可以向所有连接的客户端广播消息。

_connectionManager.GetHubContext<MyHub>().Clients.All.doSomethingOnClients();

作为测试,webapi 控制器操作方法中的同一行代码工作正常! (通过构造函数注入 IConnectionManager)。这让我相信我的信号器设置很好,只是我在启动 class 中得到东西的方式在某处是错误的。 GetHashCode 在启动时 IConnectionManager 和我的控制器给出了不同的哈希码。我只需要连接 ApplicationLifetime OnStartUp ...

你能帮我了解哪里出了问题吗?

public class Startup
{
    public static IServiceProvider _serviceProvider;
    public static IConnectionManager _connectionManager;
    private readonly IHostingEnvironment _hostingEnv;
    public IConfigurationRoot Configuration { get; }

    public Startup (IHostingEnvironment env)
    {
        // ...
    }
    public void ConfigureServices (IServiceCollection services)
    {               
        // ....
        services.AddSignalR(options => {
            options.Hubs.EnableDetailedErrors = true;
        });

        services.AddMvc();
        // ...
        _serviceProvider = services.BuildServiceProvider();
        _connectionManager = _serviceProvider.GetService<IConnectionManager>();
    }

    public void Configure (IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IApplicationLifetime applicationLifetime)
    {
        // ...
        applicationLifetime.ApplicationStarted.Register(OnStartUp);
        // ...
        app.UseMvc(routes => {
            routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
        });
        app.UseSignalR();
        // ...
    }

    public void OnStartUp ()
    {
        var x = _serviceProvider.GetService<MySingletonObject>();
        // MySingletonObject has a  VersionUpdated event handler
        x.VersionUpdated += OnUpdate;
    }

    private void OnUpdate (object sender, EventArgs e)
    {

         // I get here everytime my singleton gets updated fine!
         // but the following does not work  
        _connectionManager.GetHubContext<MyHub>().Clients.All.doSomethingOnClients();    
    }

}

我正在使用 "Microsoft.AspNetCore.SignalR.Server/0.2.0-alpha1-22362"。

第一件事是意识到这个版本的 SignalR 没有发布,它只是 alpha。您遇到的问题是因为您正在构建 2 个服务提供者并且他们没有相互交谈。您调用 BuildServiceProvider() 而不是将 IConnectionManager 注入您的 Configure 方法。您还可以通过将依赖项直接注入配置然后在回调中使用它们来清理大量服务定位器模式。

public class Startup
{
    public IConfigurationRoot Configuration { get; }

    public Startup (IHostingEnvironment env)
    {
        // ...
    }

    public void ConfigureServices (IServiceCollection services)
    {               
        // ....
        services.AddSignalR(options => {
            options.Hubs.EnableDetailedErrors = true;
        });

        services.AddMvc();
        // ...
    }

    public void Configure (IApplicationBuilder app, 
                        IHostingEnvironment env, 
                        ILoggerFactory loggerFactory, 
                        IApplicationLifetime applicationLifetime,
                        MySingletonObject obj,
                        IHubContext<MyHub> context)
    {
        // ...
        applicationLifetime.ApplicationStarted.Register(() => OnStartUp(obj, context));
        // ...
        app.UseMvc(routes => {
            routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
        });
        app.UseSignalR();
        // ...
    }

    public void OnStartUp(MySingletonObject obj, IHubContext<MyHub> context)
    {
        // MySingletonObject has a  VersionUpdated event handler
        obj.VersionUpdated += (sender, e) => 
        {
            context.Clients.All.doSomethingOnClients();
        };
    }

}

Even cleaner 将是另一种服务,它可以组合所有内容,这样您就不会在启动方法中有太多参数。