web-dev-qa-db-fra.com

Comment obtenir le contexte de SignalR Hub dans un noyau ASP.NET?

J'essaie d'obtenir le contexte d'un hub en utilisant les éléments suivants:

var hubContext = GlobalHost.ConnectionManager.GetHubContext<SomeHub>();

Le problème est que GlobalHost n'est pas défini. Je vois qu'il fait partie de la DLL SignalR.Core. Pour le moment, j'ai les éléments suivants dans mon fichier de projet .json, sous dépendances:

"Microsoft.AspNet.SignalR.Server": "3.0.0-*"

Si j'ajoute la dernière version disponible de Core:

"Microsoft.AspNet.SignalR.Server": "3.0.0-*",
"Microsoft.AspNet.SignalR.Core" :  "2.1.2"

Je reçois un tas d'erreurs parce que le serveur et le noyau sont en conflit. Si je les change tous les deux pour utiliser la version "3.0.0- *", tous les conflits disparaissent, mais GlobalHost est introuvable. Si je supprime le serveur et uniquement l'utilisateur Core version 2.1.2, alors GlobalHost fonctionne, mais toutes les autres choses nécessitant un serveur ne le sont évidemment pas.

Des idées?

25
user2095880

Microsoft.AspNet.SignalR.Infrastructure.IConnectionManager est un service DI injecté à travers lequel vous pouvez obtenir le contexte de hub ... Par exemple:

using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Infrastructure;
using Microsoft.AspNet.Mvc;

public class TestController : Controller
{
     private IHubContext testHub;

     public TestController(IConnectionManager connectionManager)
     {
         testHub = connectionManager.GetHubContext<TestHub>();
     }
 .....
17
Kiran Challa

IConnectionManager n'existe plus dans SignalR pour ASP.Net Core.
J'utilise HubContext pour accéder à un hub. 

public class HomeController : Controller
{
    private readonly IHubContext<LiveHub> _hubContext;

    public HomeController(IHubContext<LiveHub> hubContext)
    {
        _hubContext = hubContext;
    }

    public void SendToAll(string message)
    {
        _hubContext.Clients.All.InvokeAsync("Send", message);
    }
}

J'utilise .net core 2.0.0 et SignalR 1.0.0-alpha1-final

60
Soren

J'ai ajouté du code à mon fichier Startup.cs pour récupérer une référence au ConnectionManager que vous pouvez ensuite utiliser pour créer un GetHubContext à tout moment et à tout moment dans votre code. Semblable à la réponse de Nimo mais un peu différent, peut-être plus simple.

services.AddSignalR(options =>
{
    options.Hubs.EnableDetailedErrors = true;
});

var provider = services.BuildServiceProvider();

//Hold on to the reference to the connectionManager
var connManager = provider.GetService(typeof(IConnectionManager)) as IConnectionManager;

//Use it somewhere else
var hub = connManager.GetHubContext<SignalHub>();
2
Matt Watson

Pour utiliser le concentrateur dans un service de backgroud, en plus des contrôleurs, vous devez utiliser l'interface IHostedService et obtenir le concentrateur par ID.

public class MyBackgroundService : IHostedService, IDisposable
{
    public static IHubContext<NotifierHub> HubContext;

    public MyBackgroundService(IHubContext<NotifierHub> hubContext)
    {
        HubContext = hubContext;
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        //TODO: your start logic, some timers, singletons, etc
        return Task.CompletedTask;
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        //TODO: your stop logic
        return Task.CompletedTask;
    }

    public void Dispose()
    {
    }
}

Ensuite, vous pouvez appeler votre hub de n'importe où dans votre code à partir du champ statique HubContext:

MyBackgroundService.HubContext.Clients.All.SendAsync("UpdateData", myData).Wait();

En savoir plus sur IHostedService: https://docs.Microsoft.com/en-us/aspnet/core/fundamentals/Host/hosted-services?view=aspnetcore-2.1

Vous pouvez créer et démarrer une minuterie dans MyBackgroundService et appeler le concentrateur dans ElapsedEvent.

1
user1203003

Je devais pouvoir accéder au contexte du concentrateur de l'extérieur du fil de requête de l'application, car je m'abonnais aux messages NServicebus et je devais pouvoir déclencher une fonction client lorsque je recevais un message.

Voici comment je l'ai trié:

public static IServiceProvider __serviceProvider;

puis lors de la configuration de démarrage 

app.UseServices(services =>
        {
            __serviceProvider = new ServiceCollection()
            .BuildServiceProvider(CallContextServiceLocator.Locator.ServiceProvider);
        });

Puis n'importe où ailleurs dans l'application aspN vNext (tout autre thread)

 var manager = Startup.__serviceProvider.GetRequiredService<IConnectionManager>();
            var hub = manager.GetHubContext<ChatHub>();

J'espère que cela t'aides!

1
nimo