![](/img/trans.png)
[英]How do you get a reference to an ASP.NET Core SignalR hub context outside of a controller?
[英]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.