Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Концентратор SignalR — это ключевая абстракция для отправки сообщений клиентам, подключенным к серверу SignalR. Кроме того, можно отправлять сообщения из других мест в приложении с помощью IHubContext службы. В этой статье объясняется, как получить доступ к SignalRIHubContext, чтобы отправлять уведомления клиентам вне центра.
Note
IHubContext предназначен для отправки уведомлений клиентам; он не используется для вызова методов на Hub.
Просмотреть или скачать образец кода (описание загрузки)
Получить экземпляр IHubContext
В ASP.NET Core SignalRможно получить доступ к экземпляру IHubContext с помощью внедрения зависимостей. Вы можете внедрить экземпляр IHubContext в контроллер, промежуточное ПО или другую службу DI. Используйте экземпляр для отправки сообщений клиентам.
Внедрите экземпляр IHubContext в контроллер
Вы можете внедрить экземпляр IHubContext в контроллер, добавив его в конструктор:
public class HomeController : Controller
{
private readonly IHubContext<NotificationHub> _hubContext;
public HomeController(IHubContext<NotificationHub> hubContext)
{
_hubContext = hubContext;
}
}
Имея доступ к экземпляру IHubContext, вызывайте клиентские методы так, как если бы вы были в самом хабе:
public async Task<IActionResult> Index()
{
await _hubContext.Clients.All.SendAsync("Notify", $"Home page loaded at: {DateTime.Now}");
return View();
}
Получение экземпляра IHubContext в промежуточном ПО
Получите доступ к IHubContext в конвейере ПО промежуточного слоя следующим образом:
app.Use(async (context, next) =>
{
var hubContext = context.RequestServices
.GetRequiredService<IHubContext<ChatHub>>();
//...
if (next != null)
{
await next.Invoke();
}
});
Note
Когда клиентские методы вызываются из-за пределов Hub класса, вызывающий объект не связан с вызовом. Поэтому нет доступа к свойствам ConnectionId, Caller и Others.
Приложения, которые должны сопоставить пользователя с идентификатором подключения и сохранить это сопоставление, может выполнить одно из следующих действий:
- Сохраняйте сопоставление отдельных или нескольких подключений в виде групп. Дополнительные сведения см. в SignalR разделе "Группы".
- Сохраняйте сведения о подключении и пользователе через одну службу. Дополнительные сведения см. в статье "Внедрение служб в концентратор ". Служба singleton может использовать любой метод хранения, например:
- Хранилище в оперативной памяти в виде словаря.
- Постоянное внешнее хранилище. Например, база данных или служба хранилища таблиц Azure с использованием пакета NuGet Azure.Data.Tables.
- Передайте идентификатор подключения между клиентами.
Получение экземпляра IHubContext из IHost
Доступ к IHubContext из веб-узла полезен для интеграции с компонентами вне ASP.NET Core, например при использовании сторонних платформ внедрения зависимостей:
public class Program
{
public static void Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
var hubContext = host.Services.GetService(typeof(IHubContext<ChatHub>));
host.Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder => {
webBuilder.UseStartup<Startup>();
});
}
Внедрить строго типизированный HubContext
Чтобы внедрить строго типизированный HubContext, убедитесь, что центр наследует от Hub<T>. Внедрите это через интерфейс IHubContext<THub, T>, а не IHubContext<THub>.
public class ChatController : Controller
{
public IHubContext<ChatHub, IChatClient> _strongChatHubContext { get; }
public ChatController(IHubContext<ChatHub, IChatClient> chatHubContext)
{
_strongChatHubContext = chatHubContext;
}
public async Task SendMessage(string user, string message)
{
await _strongChatHubContext.Clients.All.ReceiveMessage(user, message);
}
}
Дополнительные сведения см. в разделе "Использование строго типизированных центров ".
Использование IHubContext в универсальном коде
Внедрённый объект IHubContext<THub> можно привести к IHubContext без указания обобщённого типа Hub.
class MyHub : Hub
{ }
class MyOtherHub : Hub
{ }
app.Use(async (context, next) =>
{
var myHubContext = context.RequestServices
.GetRequiredService<IHubContext<MyHub>>();
var myOtherHubContext = context.RequestServices
.GetRequiredService<IHubContext<MyOtherHub>>();
await CommonHubContextMethod((IHubContext)myHubContext);
await CommonHubContextMethod((IHubContext)myOtherHubContext);
await next.Invoke();
}
async Task CommonHubContextMethod(IHubContext context)
{
await context.Clients.All.SendAsync("clientMethod", new Args());
}
Это полезно, если:
- Создание библиотек, которые не ссылаются на конкретный тип
Hub, используемый приложением. - Написание кода, который является универсальным и может применяться к нескольким различным
Hubреализациям
Дополнительные ресурсы
ASP.NET Core