hangfire初始化的配置方法 :UseHangfire 。
public static class OwinBootstrapper { /// <summary> /// Bootstraps Hangfire components using the given configuration /// action and maps Hangfire Dashboard to the app builder pipeline /// at the configured path ('/hangfire' by default). /// </summary> /// <param name="app">The app builder</param> /// <param name="configurationAction">Configuration action</param> public static void UseHangfire([NotNull] this IAppBuilder app,[NotNull] Action<IBootstrapperConfiguration> configurationAction) { if (app == null) throw new ArgumentNullException("app"); if (configurationAction == null) throw new ArgumentNullException("configurationAction"); // 初始化配置,給了默認值 var configuration = new BootstrapperConfiguration(); // 委托 賦值 configurationAction(configuration); if (configuration.Activator != null) { JobActivator.Current = configuration.Activator; } if (configuration.Storage == null) { throw new InvalidOperationException("Job storage was not configured. Please call either `UseStorage` method or its overloads."); } // 獲取當前的存儲方式 JobStorage.Current = configuration.Storage; // 通過UseFilter()將配置的過濾器放入容器中 foreach (var filter in configuration.Filters) { GlobalJobFilters.Filters.Add(filter); } // 通過UseServers()將配置的過濾器放入容器中 ,如果需要分布式配置的話,在客戶端就不要配置server foreach (var server in configuration.Servers) { app.RunHangfireServer(server()); } // 將Route和權限filter注入到owin管道中 app.MapHangfireDashboard(configuration.DashboardPath, configuration.AuthorizationFilters); } }
用委托的方式來處理而不是讓開發人員自己去實現IBootstrapperConfiguration接口
這種方式確實開發人員使用上更方便了。
public static void MapHangfireDashboard( [NotNull] this IAppBuilder app, string dashboardPath, IEnumerable<IAuthorizationFilter> authorizationFilters, JobStorage storage) { if (app == null) throw new ArgumentNullException("app"); SignatureConversions.AddConversions(app); app.Map(dashboardPath,subApp => subApp.Use<DashboardMiddleware>( storage, DashboardRoutes.Routes, authorizationFilters)); }
MapHangfireDashboard方法是將DashboardMiddleware注冊到own管道中
dashboardPath默認值是“/hangfire” ,也就是說當你通過 Http://www.xxx.com/hangfire 訪問的每個請求都會進入DashboardMiddleware
DashboardMiddleware繼承了OwinMiddleware
// 方法在DashboardMiddleware內 public override Task Invoke(IOwinContext context) { // RouteCollection 是路由規則集合, var dispatcher = _routes.FindDispatcher(context.Request.Path.Value); if (dispatcher == null) { // 下一個OwinMiddleware中去處理 // 一個請求會有多個OwinMiddleware return Next.Invoke(context); } foreach (var filter in _authorizationFilters) { if (!filter.Authorize(context.Environment)) { context.Response.StatusCode = (int) HttpStatusCode.Unauthorized; return Task.FromResult(false); } } // 輸出內容 var dispatcherContext = new RequestDispatcherContext( _storage, context.Environment, dispatcher.Item2); return dispatcher.Item1.Dispatch(dispatcherContext); }
RequestDispatcherContext 內部調度實現相對有些復雜,暫時沒時間去研究,我機會再分享了。