¿Cómo obtener SignalR Hub Context en un Core ASP.NET?
signalr net core (5)
Estoy tratando de obtener el contexto para un hub usando lo siguiente:
var hubContext = GlobalHost.ConnectionManager.GetHubContext<SomeHub>();
El problema es que GlobalHost no está definido. Veo que es parte de la dll SignalR.Core. En este momento, tengo lo siguiente en mi archivo .json de proyecto, bajo dependencias:
"Microsoft.AspNet.SignalR.Server": "3.0.0-*"
Si agrego la última versión disponible de Core:
"Microsoft.AspNet.SignalR.Server": "3.0.0-*",
"Microsoft.AspNet.SignalR.Core" : "2.1.2"
Me sale un montón de errores porque el servidor y el núcleo son conflictivos. Si los cambio para que utilicen la versión "3.0.0- *", todos los conflictos desaparecen, pero no se puede encontrar GlobalHost. Si elimino Server, y solo el usuario Core versión 2.1.2, GlobalHost funciona, pero todas las otras cosas que necesitan Server, obviamente no lo hacen.
¿Algunas ideas?
Agregué algo de código a mi Startup.cs para obtener una referencia al ConnectionManager que luego puede usar para hacer un GetHubContext en cualquier momento desde cualquier lugar en su código. Similar a la respuesta de Nimo pero un poco diferente, quizás más 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>();
Necesitaba poder acceder al Contexto del concentrador desde fuera del subproceso de solicitud de la aplicación, porque estaba suscribiéndome a los mensajes de NServicebus y necesitaba poder activar una función de cliente cuando recibí un mensaje.
Así es como lo solucioné:
public static IServiceProvider __serviceProvider;
luego durante la configuración de inicio
app.UseServices(services =>
{
__serviceProvider = new ServiceCollection()
.BuildServiceProvider(CallContextServiceLocator.Locator.ServiceProvider);
});
Luego, en cualquier otro lugar de la aplicación vNext asp.net (cualquier otro hilo)
var manager = Startup.__serviceProvider.GetRequiredService<IConnectionManager>();
var hub = manager.GetHubContext<ChatHub>();
¡Espero que esto ayude!
Para usar el concentrador en un servicio de backgroud, además de los controladores, debe usar la interfaz IHostedService y obtener el concentrador por DI.
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()
{
}
}
Luego puede llamar a su hub desde cualquier lugar en su código desde el campo estático HubContext:
MyBackgroundService.HubContext.Clients.All.SendAsync("UpdateData", myData).Wait();
Obtenga más información sobre IHostedService: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-2.1
Puede crear e iniciar un temporizador en MyBackgroundService y llamar al concentrador en ElapsedEvent.
IConnectionManager ya no existe en SignalR para ASP.Net Core.
He estado usando HubContext
para obtener acceso a 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);
}
}
Estoy usando .net core 2.0.0 y SignalR 1.0.0-alpha1-final
Microsoft.AspNet.SignalR.Infrastructure.IConnectionManager
es un servicio de inyección DI a través del cual puede obtener el contexto del hub ... Por ejemplo:
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>();
}
.....