安裝Hangfire
新建ASP.NET Core空 項(xiàng)目,.Net Core版本3.1
往*.csproj添加包引用,添加新的PackageReference標(biāo)記。如下所示。請(qǐng)注意,下面代碼段中的版本可能已經(jīng)過(guò)時(shí),如有需要,請(qǐng)使用nuget獲取最新版本。
<ItemGroup>
<PackageReference Include="Hangfire.Core" Version="1.7.28" />
<PackageReference Include="Hangfire.SqlServer" Version="1.7.28" />
<PackageReference Include="Hangfire.AspNetCore" Version="1.7.28" />
</ItemGroup>
創(chuàng)建數(shù)據(jù)庫(kù)
從上面的代碼片段中可以看到,在本文中,我們將使用SQL Server作為作業(yè)存儲(chǔ)。在配置Hangfire之前,您需要為它創(chuàng)建一個(gè)數(shù)據(jù)庫(kù),或者使用現(xiàn)有的數(shù)據(jù)庫(kù)。下面的配置字符串指向本地計(jì)算機(jī)上SQLEXPRESS實(shí)例中的HangfireTest數(shù)據(jù)庫(kù)。
您可以使用SQLServerManagementStudio或任何其他方式執(zhí)行以下SQL命令。如果您使用的是其他數(shù)據(jù)庫(kù)名稱(chēng)或?qū)嵗?qǐng)確保在接下來(lái)的步驟中配置Hangfire時(shí)更改了連接字符串。
CREATE DATABASE [HangfireTest]
GO
配置Settings
下面將定義HangfireConnection連接來(lái)進(jìn)行表遷移,同時(shí)AspNetCore與Hangfire進(jìn)行了日志記錄集成。Hangfire的日志信息有時(shí)非常重要,有助于診斷不同的問(wèn)題。信息級(jí)別允許查看Hangfire的工作情況,警告和更高的日志級(jí)別有助于調(diào)查問(wèn)題,建議調(diào)整日志級(jí)別
{
"ConnectionStrings": {
"HangfireConnection": "Server=.\sqlexpress;Database=HangfireTest;Integrated Security=SSPI;"
},
"Logging": {
"LogLevel": {
"Default": "Warning",
"Hangfire": "Information"
}
}
}
更新應(yīng)用程序設(shè)置后,打開(kāi)Startup.cs文件。startup類(lèi)是.NET CORE應(yīng)用程序的配置。首先,我們需要導(dǎo)入Hangfire名稱(chēng)空間,由于建的是空項(xiàng)目,所以還需要導(dǎo)入Configuration.
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Hangfire;
using Hangfire.SqlServer;
注冊(cè)服務(wù)
使用asp.netcore內(nèi)置DI注入Hangfire服務(wù)
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
// Add Hangfire services.
services.AddHangfire(configuration => configuration
.SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings()
.UseSqlServerStorage(Configuration.GetConnectionString("HangfireConnection"), new SqlServerStorageOptions
{
CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
QueuePollInterval = TimeSpan.Zero,
UseRecommendedIsolationLevel = true,
DisableGlobalLocks = true
}));
// Add the processing server as IHostedService
services.AddHangfireServer();
}
添加Hangfire面板
如果只是作為后臺(tái)作業(yè),也可不使用面板功能,按需添加
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/", async context =>
{
await context.Response.WriteAsync("Hello World!");
});
endpoints.MapHangfireDashboard();
});
BackgroundJob.Enqueue(() => Console.WriteLine("測(cè)試"));
}
運(yùn)行程序
生成數(shù)據(jù)表
訪(fǎng)問(wèn)
http://localhost:5000/hangfire
添加Hangfire面板授權(quán)
新建MyAuthorizationFilter.cs
public class MyAuthorizationFilter : IDashboardAuthorizationFilter
{
public bool Authorize(DashboardContext context)
{
var httpContext = context.GetHttpContext();
string header = httpContext.Request.Headers["Authorization"];//獲取授權(quán)
if(header == null)
return AuthenicateLogin();
//解析授權(quán)
var authHeader = AuthenticationHeaderValue.Parse(header);
var credentialBytes = Convert.FromBase64String(authHeader.Parameter);
var credentials = Encoding.UTF8.GetString(credentialBytes).Split(new[] { ':' }, 2);
var username = credentials[0];
var password = credentials[1];
//驗(yàn)證登錄
if (username == "admin" && password =="123456")
return true;
else
return AuthenicateLogin();
//跳轉(zhuǎn)簡(jiǎn)單登錄界面
bool AuthenicateLogin()
{
httpContext.Response.StatusCode = 401;
httpContext.Response.Headers.Append("WWW-Authenticate", "Basic realm="Hangfire Dashboard"");
context.Response.WriteAsync("Authenticatoin is required.");
return false;
}
}
}
Hangfire面板修改
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapHangfireDashboard(new DashboardOptions
{
Authorization = new[] { new MyAuthorizationFilter() }
});
endpoints.MapGet("/", async context =>
{
await context.Response.WriteAsync("Hello World!");
});
});
BackgroundJob.Enqueue(() => Console.WriteLine("測(cè)試"));
}
運(yùn)行程序