Контекст концентратора SignalR ASP.NET Core RC2 вне потока запроса

В настоящее время я пробую RC2 выпуск ASP.NET Core, и у меня возникла проблема с SignalR. Мне нужно иметь возможность отправлять сообщения клиенту вне потока запроса.

Теперь в полной платформе .NET вы можете сделать это так:

var context = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
context.Clients.<SendMessage>()

Но в ASP.NET Core нет GlobalHost.

Я нашел похожий вопрос: Как получить контекст концентратора SignalR в проекте vNext?

Если второй ответ предоставляет метод для получения контекста концентратора вне потока запроса, но это также не работает в ASP.NET Core.

Итак, мой вопрос: как я могу получить контекст концентратора вне области запроса в ASP.NET Core?


person larzz11    schedule 19.05.2016    source источник


Ответы (3)


Вам нужно будет загрузить текущую версию github из: Signalr Github (Commit: b95ac7b < / strong> на момент написания)

После того, как у вас есть это и вы загрузили решение или добавили все три проекта к существующему решению, вам нужно будет изменить project.json во всех трех проектах.

Microsoft.AspNetCore.SignalR.Server - project.json

Вы увидите ссылки на версию 1.1.0- * (RC3) каждой сборки. Измените их на текущий RC2, пока не увидите следующее

"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",

Теперь сохраните файл, и зависимости обновятся.

Сделайте то же самое с файлами Messaging и Infrastructure project.json, заменив любые 1.1.0- * на 1.0.0.

Как только это будет сделано, вы можете добавить ссылку на проект в свой основной проект Microsoft.AspNetCore.SignalR.Server.

Теперь, когда он загружен, откройте файл Startup.cs

Внутри метода ConfigureServices добавьте:

 services.AddSignalR();

Внутри метода Настроить добавьте:

 app.UseSignalR();

Затем добавьте оператор using и импортируйте пространство имен Infrastructure следующим образом:

using Microsoft.AspNetCore.SignalR.Infrastructure;

И, наконец, создайте в Startup.cs статическое свойство с именем ConnectionManager следующим образом:

public static IConnectionManager ConnectionManager;

Наконец, добавьте свойство IServiceProvider в метод Configure в Startup.cs (необходимо импортировать пространство имен System). Затем загрузите ConfigurationManager из этого.

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

Теперь в ваших хабах / где-либо еще, вместо использования Globalhost, просто используйте команду startup. Например:

IHubContext context = Startup.ConnectionManager.GetHubContext<SomeHub>();
context.Clients.All.someMethod();
person Dave    schedule 08.08.2016
comment
Есть ли причина не просто вводить IConnectionManager в сервисы? - person steamrolla; 08.03.2017
comment
Работал отлично; не пришлось гадать с project.json хотя (SignalR Core находится в более новой версии, но все еще альфа) - person brichins; 09.03.2017
comment
привет, откуда вы взяли эту информацию? я не могу найти документацию по ядру signalr? - person SHM; 10.07.2017
comment
см. github.com/aspnet/SignalR/issues/498#issuecomment-304768866 Microsoft.AspNetCore.SignalR.Server устарел. Это решение больше не может применяться - person Lorenzo Isidori; 27.02.2019
comment
Ага. Раньше это была хорошая информация, но теперь она вводит в заблуждение и должна быть удалена. - person joelmdev; 14.11.2019

Другая возможность - вставить свой HubContext в ваш контроллер, например:

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

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

Тогда вы также можете позвонить

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

Но тогда вы будете направлять методы вызова на всех клиентов.

См. Также метод Call SignalR Core Hub из контроллера для другая возможность

person Stephu    schedule 26.10.2017

Если вы хотите использовать контекст вашего хаба вне контроллера, как в службе, вы можете попробовать это.

В вашем классе StartUp:

    private IHubContext<SomeHub> hubContext;

В методе ConfigureServices вставьте hubContext в свою службу:

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

В методе Configure:

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

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

Это решило мою проблему с невозможностью вызывать клиентские методы из класса серверной службы.

person Max    schedule 15.08.2019
comment
что, если SomeService имеет несколько зависимостей, а не только hubcontext? - person Divyang Desai; 21.01.2020