web-dev-qa-db-ja.com

別のオブジェクト内からSignalRコアのハブコンテキストを取得する

_Microsoft.AspNetCore.SignalR_(最新リリース)を使用していて、Controllerではない別のオブジェクト内からハブコンテキストを取得したいと考えています。 「完全な」SignalRでは、GlobalHost.ConnectionManager.GetHubContext<MyCoolHub>();を使用できます

ControllerのCtorにパラメーターとして_Microsoft.AspNetCore.SignalR.IHubContext<MyCoolHub>_を追加するだけの多くの例を見てきましたが、それ以外の例(動作しない)はありません。

ETA:

だから、これは私が働いているものです。これはハックですか?

_public class MyHub : Hub
    public static IHubContext<MyHub> GlobalContext { get; private set; }
    public MyHub(IHubContext<MyHub> ctx){
        GlobalContext = ctx;
    }
}
_

それから私はそれをそう呼ぶことができます:

_await MyHub.GlobalContext.Clients.All.InvokeAsync(...)
_
8
Andy

IHubContext<MyHub> hubContext呼び出し側コンストラクタ。

静的プロパティを作成せずに、.netコアのデフォルトのDIコンテナーメカニズムを使用することをお勧めします。

参照してください ハブへの参照を取得するにはどうすればよいですか?

public class MyHub : Hub
{
}

public class CallingSideClass
{
    private readonly IHubContext<MyHub> _hubContext;

    public CallingSideClass(IHubContext<MyHub> hubContext)
    {
        _hubContext = hubContext;
    }

    public async Task FooMethod(...)
    {
        await _hubContext.Clients.All.InvokeAsync(...);
    }
}

public class Startup
{...
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSignalR();
        services.AddScoped<CallingSideClass>();
    }
    ... 
}
8
idubnori

だから、受け入れられた答えから この例 を見た後、私は彼がどこに行くのか全くわからなかったので、私はいくつかのことを試しました、そして私は彼の言っていることを理解しましたしたがって、将来この問題が発生する人のために、その例を完全に機能する例に変更したいと思います。

したがって、例のように「共有メソッド」を作成します。

using Microsoft.AspNetCore.SignalR;
using System.Threading.Tasks;

namespace YouDontNeedToKnow.Core.Main.Hubs
{
    internal class HubMethods<THub> where THub : Hub
    {
        private readonly IHubContext<THub> _hubContext;

        public HubMethods(IHubContext<THub> hubContext)
        {
            _hubContext = hubContext;
        }

        public Task InvokeOnGroupAsync(string groupName, string method, params object[] args) =>
            _hubContext.Clients.Group(groupName).InvokeAsync(method, args);

        public Task InvokeOnAllAsync(string method, params object[] args) =>
            _hubContext.Clients.All.InvokeAsync(method, args);

        public Task AddConnectionIdToGroupAsync(string connectionId, string groupName) =>
            _hubContext.Groups.AddAsync(connectionId, groupName);

        // ...
    }
}

次に、Hubオブジェクトに、次のようにコンストラクターを追加します。

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;

namespace YouDontNeedToKnow.Core.Main.Hubs
{
    internal class MyHub : Hub
    {
        public static string HubName => "myHub";

        private readonly HubMethods<MyHub> _hubMethods;

        public PlayerServicesHub(HubMethods<MyHub> hubMethods)
        {
            _hubMethods = hubMethods;
        }

        public override Task OnConnectedAsync()
        {
            return base.OnConnectedAsync();
        }
    }
}

あなたのStartup.cs、次のように共有クラスを挿入します。

public void ConfigureServices(IServiceCollection services)
{
    services.AddTransient<HubMethods<MyHub>>();
    services.AddSignalR();
    services.AddMvc();
}

これは通常どおり機能します。

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IServiceProvider sp)
{
    app.UseDefaultFiles();
    app.UseStaticFiles();
    app.UseSignalR(routes =>
    {
        routes.MapHub<MyHub>(MyHub.HubName);
    });
    app.UseMvc();
    // This is just an example line of how you can get the hub with context:
    var myHub = sp.GetService<HubMethods<MyHub>>();
}
1
Andy