簡體   English   中英

如何將SignalR集線器上下文傳遞到ASP .NET Core 2.1上的Hangfire作業?

[英]How can I pass a SignalR hub context to a Hangfire job on ASP .NET Core 2.1?

如何將SignalR集線器上下文傳遞到ASP .NET Core 2.1上的Hangfire作業?

似乎由於將參數傳遞給Hangfire是通過序列化/反序列化完成的,因此Hangfire似乎很難重構SignalR集線器上下文。

我使用以下命令調度作業(在我的控制器中):

BackgroundJob.Schedule(() => _hubContext.Clients.All.SendAsync(
        "MyMessage",
        "MyMessageContent", 
        System.Threading.CancellationToken.None), 
    TimeSpan.FromMinutes(2));

然后2分鍾后,當作業嘗試執行時,出現錯誤:

Newtonsoft.Json.JsonSerializationException:無法創建類型為Microsoft.AspNetCore.SignalR.IClientProxy的實例。 類型是接口或抽象類,無法實例化。

任何想法?

更新1

我最終使用了Startup.cs中定義的靜態上下文,並從Configure()分配了該上下文

hbctx = app.ApplicationServices.GetRequiredService<IHubContext<MySignalRHub>>(); 

因此,現在,Hangfire計划使用靜態上下文的中心幫助程序:

BackgroundJob.Schedule(() => new MyHubHelper().Send(), TimeSpan.FromMinutes(2)); 

中心幫助器通過Startup.hbctx獲取上下文

即使這樣做有效,也有點臭

更新2

我還嘗試了在沒有構造函數注入的情況下Access SignalR Hub中使用該方法:

我的后台作業調度為:

BackgroundJob.Schedule(()=> Startup.GetService()。SendOutAlert(2),TimeSpan.FromMinutes(2));

但是這次,當我到達上面的行時,我有一個例外:

執行請求System.ObjectDisposedException時發生未處理的異常:無法訪問已處置的對象。 對象名稱:“ IServiceProvider”。

更新3

謝謝大家 解決方案是創建一個幫助程序,該幫助程序通過DI的構造函數獲取集線器上下文,然后使用hangfire安排幫助程序方法Send作為后台作業。

public interface IMyHubHelper
{
    void SendOutAlert(String userId);
}

public class MyHubHelper : IMyHubHelper
{
    private readonly IHubContext<MySignalRHub> _hubContext;

    public MyHubHelper(IHubContext<MySignalRHub> hubContext)
    {
        _hubContext = hubContext;
    }

    public void SendOutAlert(String userId)
    {
        _hubContext.Clients.All.SendAsync("ReceiveMessage", userId, "msg");
    }
}

然后使用以下命令從任何地方啟動后台作業:

BackgroundJob.Schedule<MyHubHelper>( x => x.SendOutAlert(userId), TimeSpan.FromMinutes(2));

使用Schedule<T>泛型,您應該能夠利用框架的依賴注入功能。

BackgroundJob.Schedule<IHubContext<MySignalRHub>>(hubContext => 
    hubContext.Clients.All.SendAsync(
        "MyMessage",
        "MyMessageContent", 
        System.Threading.CancellationToken.None), 
    TimeSpan.FromMinutes(2));

Nkosi的建議使用Schedule<T>泛型的答案將我帶到了我使用的最終解決方案:

首先,我的MySignalRHub只是一個繼承自Hub的空類。

public class MySignalRHub 
{
}

然后,我創建了一個集線器幫助程序,它在MySignalRHub上維護一個集線器上下文。 該hubcontext在輔助類通過ASP.Net核心內建DI機構噴射(如解釋在這里 )。

助手類:

public class MyHubHelper : IMyHubHelper
{
    private readonly IHubContext<MySignalRHub> _hubContext;

    public MyHubHelper(IHubContext<MySignalRHub> hubContext)
    {
        _hubContext = hubContext;
    }

    public void SendData(String data)
    {
        _hubContext.Clients.All.SendAsync("ReceiveMessage", data);
    }
}

助手界面:

public interface IMyHubHelper
{
    void SendData(String data);
}

最后,我可以使用hangfire從代碼中的任何地方調度集線器幫助程序的SendData()方法作為后台作業,它具有:

BackgroundJob.Schedule<MyHubHelper>(h => h.SendData(myData), TimeSpan.FromMinutes(2));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM