ASP.NET Core RC2 SignalR Hub Context outside request thread

删除回忆录丶 提交于 2019-11-27 19:30:25

You will have to pull the current github version from : Signalr Github (Commit: b95ac7b at time of writing)

Once you have this, and have loaded the solution, or added all three of the projects to your existing solution, you will need to change project.json in all three projects.

Microsoft.AspNetCore.SignalR.Server - project.json

You will see references to version 1.1.0-* (RC3) of each assembly. Change these to the current RC2, until you see the following

"Microsoft.AspNetCore.DataProtection": "1.0.0",
"Microsoft.AspNetCore.Hosting.Abstractions": "1.0.0",
"Microsoft.AspNetCore.Http.Extensions": "1.0.0",
"Microsoft.Extensions.DependencyModel": "1.0.0",

Now save the file, and the dependencies will update.

Do the same with The Messaging and Infrastructure project.json file's, replacing any 1.1.0-* with 1.0.0

Once that is done, you can add a project reference to your main project of Microsoft.AspNetCore.SignalR.Server

Now that you have that loaded, Open your Startup.cs

Inside the ConfigureServices method, add:

 services.AddSignalR();

Inside the Configure Method add:

 app.UseSignalR();

Next, add a using statement and import the Infrastructure namespace as follows:

using Microsoft.AspNetCore.SignalR.Infrastructure;

And finally Create a static property in Startup.cs called ConnectionManager as follows:

public static IConnectionManager ConnectionManager;

Finally add a IServiceProvider property to the Configure method in Startup.cs (Need to import the System namespace). Then Load the ConfigurationManager from this.

 public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IServiceProvider serviceProvider)
    {
        ConnectionManager = serviceProvider.GetService<IConnectionManager>();

Now, in your hubs / anywhere else, instead of using Globalhost, Simply use startup. For example:

IHubContext context = Startup.ConnectionManager.GetHubContext<SomeHub>();
context.Clients.All.someMethod();

Another possibility is to inject your HubContext into your controller like:

public VarDesignCommController(IHubContext<VarDesignHub> hubcontext)
{
    HubContext = hubcontext;
    ...
}

private IHubContext<VarDesignHub> HubContext
{
    get;
    set;
}

Then you can also call

await this.HubContext.Clients.All.InvokeAsync("Completed", id);

But then you will direct call methods on all clients.

See also Call SignalR Core Hub method from Controller for an other possibility

If you want to use your hub context outside of the controller like in a service, you can try this.

In your StartUp class:

    private IHubContext<SomeHub> hubContext;

In the ConfigureServices method inject the hubContext in your service:

    services.AddScoped<ISomeService, SomeService>((factory) => {
        return new SomeService(hubContext);
    });

In the Configure method:

    app.UseSignalR(routes =>
        {
            routes.MapHub<SomeHub>("/hubRoute");
        });

        hubContext = app.ApplicationServices.GetService<IHubContext<SomeHub>>();

This solved my issue of not being able to call client methods from a backend service class.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!