web-dev-qa-db-ja.com

リクエストスレッド外のASP.NET Core RC2 SignalRハブコンテキスト

現在、RC2ASP.NET Coreリリースを試しており、SignalRで問題が発生しています。リクエストスレッド外のクライアントにメッセージを送信できるようにする必要があります。

完全な.NETフレームワークでは、次のように実行できます。

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

しかし、ASP.NET CoreにはGlobalHostはありません。

私は同様の質問を見つけました: vNextプロジェクトでSignalRハブコンテキストを取得する方法?

2番目の回答は、要求スレッド外でハブコンテキストを取得する方法を提供しますが、これもASP.NET Coreでは機能しません。

だから私の質問は:ASP.NET Coreでリクエストスコープ外にハブコンテキストを取得するにはどうすればよいですか?

18
larzz11

現在のgithubバージョンを以下からプルする必要があります: Signalr Github (コミット:b95ac7b執筆時点)

これを取得し、ソリューションをロードするか、3つのプロジェクトすべてを既存のソリューションに追加したら、3つのプロジェクトすべてで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",

ファイルを保存すると、依存関係が更新されます。

TheMessagingおよびInfrastructureproject.jsonファイルで同じことを行い、置き換えます1.1.0- *と1.0.0

それが完了したら、Microsoft.AspNetCore.SignalR.Serverのメインプロジェクトにプロジェクト参照を追加できます。

ロードしたので、Startup.csを開きます

ConfigureServicesメソッド内に、以下を追加します。

 services.AddSignalR();

Configureメソッドの内部に追加:

 app.UseSignalR();

次に、次のようにusingステートメントを追加し、Infrastructure名前空間をインポートします。

using Microsoft.AspNetCore.SignalR.Infrastructure;

最後に、次のように、ConnectionManagerと呼ばれるStartup.csに静的プロパティを作成します。

public static IConnectionManager ConnectionManager;

最後に、IServiceProviderプロパティをStartup.csのConfigureメソッドに追加します(システム名前空間をインポートする必要があります)。次に、これからConfigurationManagerをロードします。

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

今、あなたのハブ/他のどこでも、Globalhostを使用する代わりに、単にスタートアップを使用してください。例えば:

IHubContext context = Startup.ConnectionManager.GetHubContext<SomeHub>();
context.Clients.All.someMethod();
16
Dave

別の可能性は、次のようにHubContextをコントローラーに注入することです。

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

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

その後、あなたも呼び出すことができます

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

ただし、すべてのクライアントで呼び出しメソッドを直接指定します。

他の可能性については コントローラーからSignalRコアハブメソッドを呼び出す も参照してください

7
Stephu

サービスのようにコントローラーの外でハブコンテキストを使用する場合は、これを試すことができます。

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>>();

これにより、バックエンドサービスクラスからクライアントメソッドを呼び出せないという私の問題が解決しました。

3
Max