diff --git a/Bootstrap.Admin/Controllers/Api/RegisterController.cs b/Bootstrap.Admin/Controllers/Api/RegisterController.cs index 8a761d77..70974075 100644 --- a/Bootstrap.Admin/Controllers/Api/RegisterController.cs +++ b/Bootstrap.Admin/Controllers/Api/RegisterController.cs @@ -37,7 +37,7 @@ namespace Bootstrap.Admin.Controllers.Api public async Task Post([FromServices]IHubContext hub, [FromBody]User user) { var ret = UserHelper.Save(user); - if (ret) await SignalRManager.Send(hub.Clients.All, new MessageBody() { Category = "Users", Message = string.Format("{0}-{1}", user.UserName, user.Description) }); + if (ret) await hub.SendMessageBody(new MessageBody() { Category = "Users", Message = string.Format("{0}-{1}", user.UserName, user.Description) }, HttpContext.RequestAborted); return ret; } diff --git a/Bootstrap.Admin/Controllers/Api/TasksLogController.cs b/Bootstrap.Admin/Controllers/Api/TasksLogController.cs index 5903f92f..7e8301b0 100644 --- a/Bootstrap.Admin/Controllers/Api/TasksLogController.cs +++ b/Bootstrap.Admin/Controllers/Api/TasksLogController.cs @@ -1,8 +1,8 @@ using Longbow.Tasks; -using Longbow.Web.SignalR; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.SignalR; using System.Linq; +using System.Threading.Tasks; namespace Bootstrap.Admin.Controllers.Api { @@ -20,19 +20,19 @@ namespace Bootstrap.Admin.Controllers.Api /// /// [HttpGet] - public bool Get([FromQuery]string name, [FromServices]IHubContext hub) + public async Task Get([FromQuery]string name, [FromServices]IHubContext hub) { var sche = TaskServicesManager.GetOrAdd(name); - sche.Triggers.First().PulseCallback = t => SendTaskLog(sche, name, hub); - SendTaskLog(sche, name, hub); - return true; + sche.Triggers.First().PulseCallback = t => SendTaskLog(sche, name, hub).ConfigureAwait(false); + await SendTaskLog(sche, name, hub).ConfigureAwait(false); + return Ok(true); } - private void SendTaskLog(IScheduler sche, string name, IHubContext hub) + private async Task SendTaskLog(IScheduler sche, string name, IHubContext hub) { var t = sche.Triggers.First(); var result = $"{{\"name\": \"{name}\", \"msg\": \"Trigger({t.GetType().Name}) LastRuntime: {sche.LastRuntime} Run({t.LastResult}) NextRuntime: {sche.NextRuntime} Elapsed: {t.LastRunElapsedTime.Seconds}s\"}}"; - SignalRManager.SendTaskLog(hub.Clients.All, result).ConfigureAwait(false); + await hub.SendTaskLog(result); } } } diff --git a/Bootstrap.Admin/SignalR/SignalRManager.cs b/Bootstrap.Admin/SignalR/SignalRManager.cs deleted file mode 100644 index 050c98af..00000000 --- a/Bootstrap.Admin/SignalR/SignalRManager.cs +++ /dev/null @@ -1,43 +0,0 @@ -using Bootstrap.DataAccess; -using Microsoft.AspNetCore.SignalR; -using System; -using System.Data.Common; - -namespace Bootstrap.Admin -{ - /// - /// - /// - public static class SignalRManager - { - /// - /// - /// - /// - /// - /// - public static System.Threading.Tasks.Task Send(IClientProxy client, MessageBody args) => client.SendAsync("rev", args); - - /// - /// - /// - /// - /// - /// - public static System.Threading.Tasks.Task SendTaskLog(IClientProxy client, string args) => client.SendAsync("taskRev", args); - - /// - /// - /// - /// - /// - /// - public static async System.Threading.Tasks.Task Send(IHubContext context, Exception ex) where T : Hub - { - var category = "App"; - if (ex.GetType().IsSubclassOf(typeof(DbException))) category = "DB"; - var message = new MessageBody() { Category = category, Message = ex.Message }; - await Send(context.Clients.All, message); - } - } -} diff --git a/Bootstrap.Admin/SignalRExtensions.cs b/Bootstrap.Admin/SignalRExtensions.cs new file mode 100644 index 00000000..adc5c2c5 --- /dev/null +++ b/Bootstrap.Admin/SignalRExtensions.cs @@ -0,0 +1,47 @@ +using Bootstrap.DataAccess; +using Longbow.Web.SignalR; +using Microsoft.AspNetCore.SignalR; +using System; +using System.Data.Common; +using System.Threading; +using Task = System.Threading.Tasks.Task; + +namespace Bootstrap.Admin +{ + /// + /// SignalR 操作扩展类 + /// + public static class SignalRExtensions + { + /// + /// 推送异常信息到客户端方法扩展 + /// + /// + /// + /// + /// + public static async Task SendMessageBody(this IHubContext context, Exception ex, CancellationToken token = default) + { + var category = "App"; + if (ex.GetType().IsSubclassOf(typeof(DbException))) category = "DB"; + await context.SendMessageBody(new MessageBody() { Category = category, Message = ex.Message }, token); + } + + /// + /// 推送 MessageBody 到客户端方法扩展 + /// + /// + /// + /// + /// + public static Task SendMessageBody(this IHubContext context, MessageBody messageBody, CancellationToken token = default) => context.Clients.All.SendAsync("rev", messageBody, token); + + /// + /// 推送任务消息到客户端扩展 + /// + /// + /// + /// + public static Task SendTaskLog(this IHubContext context, string args) => context.Clients.All.SendAsync("rev", args); + } +} diff --git a/Bootstrap.Admin/Startup.cs b/Bootstrap.Admin/Startup.cs index 4f931167..6b83bde8 100644 --- a/Bootstrap.Admin/Startup.cs +++ b/Bootstrap.Admin/Startup.cs @@ -18,12 +18,12 @@ using System.Text.Unicode; namespace Bootstrap.Admin { /// - /// + /// Startup 启动配置文件 /// public class Startup { /// - /// + /// 构造函数 /// /// public Startup(IConfiguration configuration) @@ -32,13 +32,13 @@ namespace Bootstrap.Admin } /// - /// + /// 获得 系统配置项 Iconfiguration 实例 /// public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. /// - /// + /// 服务容器注入方法 /// /// public void ConfigureServices(IServiceCollection services) @@ -58,7 +58,7 @@ namespace Bootstrap.Admin services.AddIPLocator(DictHelper.ConfigIPLocator); services.AddOnlineUsers(); services.AddSignalR().AddJsonProtocalDefault(); - services.AddSignalRExceptionFilterHandler(async (client, ex) => await SignalRManager.Send(client, ex)); + services.AddSignalRExceptionFilterHandler((client, ex) => client.SendMessageBody(ex).ConfigureAwait(false)); services.AddResponseCompression(); services.AddBootstrapAdminAuthentication(); services.AddSwagger(); @@ -86,7 +86,7 @@ namespace Bootstrap.Admin // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. /// - /// + /// 管道构建方法 /// /// /// @@ -110,7 +110,11 @@ namespace Bootstrap.Admin app.UseBootstrapAdminAuthentication(RoleHelper.RetrievesByUserName, RoleHelper.RetrievesByUrl, AppHelper.RetrievesByUserName); app.UseOnlineUsers(callback: TraceHelper.Save); app.UseCacheManagerCorsHandler(); - app.UseSignalR(routes => { routes.MapHub("/NotiHub"); }); + app.UseSignalR(routes => + { + routes.MapHub("/NotiHub"); + routes.MapHub("/TaskLogHub"); + }); app.UseSwagger(Configuration["SwaggerPathBase"].TrimEnd('/')); app.UseMvc(routes => { diff --git a/Bootstrap.Admin/TaskLogHub.cs b/Bootstrap.Admin/TaskLogHub.cs new file mode 100644 index 00000000..53e618e8 --- /dev/null +++ b/Bootstrap.Admin/TaskLogHub.cs @@ -0,0 +1,12 @@ +using Longbow.Web.SignalR; + +namespace Bootstrap.Admin +{ + /// + /// 后台任务消息Hub + /// + public class TaskLogHub : SignalRHub + { + + } +} diff --git a/Bootstrap.Admin/wwwroot/js/tasks.js b/Bootstrap.Admin/wwwroot/js/tasks.js index fd5bcb3f..04326008 100644 --- a/Bootstrap.Admin/wwwroot/js/tasks.js +++ b/Bootstrap.Admin/wwwroot/js/tasks.js @@ -67,8 +67,7 @@ // open hub $taskMsg.notifi({ - url: 'NotiHub', - method: 'taskRev', + url: 'TaskLogHub', callback: function (result) { var content = this.children(); while (content.children().length > 50) {