From fa41727fcadf8d2146ac0b3bb5e2dc674554d781 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=99=BA=E8=83=BD=E5=A4=A7=E7=9F=B3=E5=A4=B4?= Date: Wed, 5 Mar 2025 10:15:06 +0800 Subject: [PATCH] v1.1.2025.0305 --- Zero.Agent/Zero.Agent.csproj | 6 +- Zero.Agent2/Zero.Agent2.csproj | 2 +- Zero.AntJob/Zero.AntJob.csproj | 10 +- Zero.Client/Zero.Client.csproj | 6 +- Zero.Console/Zero.Console.csproj | 6 +- Zero.Data/Zero.Data.csproj | 6 +- Zero.Desktop/Zero.Desktop.csproj | 6 +- Zero.GtkForm/Zero.GtkForm.csproj | 6 +- Zero.HttpServer/Zero.HttpServer.csproj | 8 +- Zero.RpcServer/Zero.RpcServer.csproj | 8 +- Zero.Server/Zero.Server.csproj | 8 +- Zero.TcpServer/Zero.TcpServer.csproj | 8 +- .../Nodes/Controllers/NodeOnlineController.cs | 37 ++--- Zero.Web/Services/NodeService.cs | 25 ++-- Zero.Web/Zero.Web.csproj | 10 +- .../Nodes/Controllers/NodeOnlineController.cs | 136 +++++++++++++----- Zero.WebApi/Services/NodeService.cs | 25 ++-- Zero.WebApi/Zero.WebApi.csproj | 12 +- .../Zero.WebSocketServer.csproj | 8 +- Zero.WebView/Zero.WebView.csproj | 6 +- Zero.Worker/Zero.Worker.csproj | 12 +- 21 files changed, 193 insertions(+), 158 deletions(-) diff --git a/Zero.Agent/Zero.Agent.csproj b/Zero.Agent/Zero.Agent.csproj index 7f4d1ed..5f3b6d4 100644 --- a/Zero.Agent/Zero.Agent.csproj +++ b/Zero.Agent/Zero.Agent.csproj @@ -24,9 +24,9 @@ - - - + + + diff --git a/Zero.Agent2/Zero.Agent2.csproj b/Zero.Agent2/Zero.Agent2.csproj index 80cb438..ff5b5d6 100644 --- a/Zero.Agent2/Zero.Agent2.csproj +++ b/Zero.Agent2/Zero.Agent2.csproj @@ -19,7 +19,7 @@ - + diff --git a/Zero.AntJob/Zero.AntJob.csproj b/Zero.AntJob/Zero.AntJob.csproj index f19e334..ec6c4f4 100644 --- a/Zero.AntJob/Zero.AntJob.csproj +++ b/Zero.AntJob/Zero.AntJob.csproj @@ -28,11 +28,11 @@ - - - - - + + + + + diff --git a/Zero.Client/Zero.Client.csproj b/Zero.Client/Zero.Client.csproj index ecea998..8506c28 100644 --- a/Zero.Client/Zero.Client.csproj +++ b/Zero.Client/Zero.Client.csproj @@ -20,9 +20,9 @@ - - - + + + diff --git a/Zero.Console/Zero.Console.csproj b/Zero.Console/Zero.Console.csproj index 8fd0e40..0d4bad1 100644 --- a/Zero.Console/Zero.Console.csproj +++ b/Zero.Console/Zero.Console.csproj @@ -25,10 +25,10 @@ - - + + - + diff --git a/Zero.Data/Zero.Data.csproj b/Zero.Data/Zero.Data.csproj index 9fc43a2..b04c58b 100644 --- a/Zero.Data/Zero.Data.csproj +++ b/Zero.Data/Zero.Data.csproj @@ -27,9 +27,9 @@ - - - + + + diff --git a/Zero.Desktop/Zero.Desktop.csproj b/Zero.Desktop/Zero.Desktop.csproj index a5acd64..3d8924e 100644 --- a/Zero.Desktop/Zero.Desktop.csproj +++ b/Zero.Desktop/Zero.Desktop.csproj @@ -26,9 +26,9 @@ - - - + + + diff --git a/Zero.GtkForm/Zero.GtkForm.csproj b/Zero.GtkForm/Zero.GtkForm.csproj index 6a433a1..2b31a4c 100644 --- a/Zero.GtkForm/Zero.GtkForm.csproj +++ b/Zero.GtkForm/Zero.GtkForm.csproj @@ -27,9 +27,9 @@ - - - + + + diff --git a/Zero.HttpServer/Zero.HttpServer.csproj b/Zero.HttpServer/Zero.HttpServer.csproj index ae239b4..07709ae 100644 --- a/Zero.HttpServer/Zero.HttpServer.csproj +++ b/Zero.HttpServer/Zero.HttpServer.csproj @@ -20,10 +20,10 @@ - - - - + + + + diff --git a/Zero.RpcServer/Zero.RpcServer.csproj b/Zero.RpcServer/Zero.RpcServer.csproj index eec6a07..25fe803 100644 --- a/Zero.RpcServer/Zero.RpcServer.csproj +++ b/Zero.RpcServer/Zero.RpcServer.csproj @@ -20,10 +20,10 @@ - - - - + + + + diff --git a/Zero.Server/Zero.Server.csproj b/Zero.Server/Zero.Server.csproj index 0d95ebe..ae05716 100644 --- a/Zero.Server/Zero.Server.csproj +++ b/Zero.Server/Zero.Server.csproj @@ -20,10 +20,10 @@ - - - - + + + + diff --git a/Zero.TcpServer/Zero.TcpServer.csproj b/Zero.TcpServer/Zero.TcpServer.csproj index 739018f..27cb925 100644 --- a/Zero.TcpServer/Zero.TcpServer.csproj +++ b/Zero.TcpServer/Zero.TcpServer.csproj @@ -20,10 +20,10 @@ - - - - + + + + diff --git a/Zero.Web/Areas/Nodes/Controllers/NodeOnlineController.cs b/Zero.Web/Areas/Nodes/Controllers/NodeOnlineController.cs index 6e64555..b4c275b 100644 --- a/Zero.Web/Areas/Nodes/Controllers/NodeOnlineController.cs +++ b/Zero.Web/Areas/Nodes/Controllers/NodeOnlineController.cs @@ -1,19 +1,12 @@ -using Microsoft.AspNetCore.Mvc; -using Zero.Data.Nodes; +using System.ComponentModel; +using Microsoft.AspNetCore.Mvc; using NewLife; using NewLife.Cube; -using NewLife.Cube.Extensions; -using NewLife.Cube.ViewModels; -using NewLife.Log; -using NewLife.Web; -using XCode.Membership; -using static Zero.Data.Nodes.NodeOnline; -using Stardust; -using System.ComponentModel; using NewLife.Remoting.Extensions.Services; using NewLife.Remoting.Models; -using NewLife.Serialization; -using Zero.Web.Areas.Nodes; +using NewLife.Web; +using XCode.Membership; +using Zero.Data.Nodes; namespace Zero.Web.Areas.Nodes.Controllers; @@ -74,19 +67,15 @@ public async Task CheckUpgrade() var ts = new List(); foreach (var item in SelectKeys) { - var online = FindById(item.ToInt()); + var online = NodeOnline.FindById(item.ToInt()); if (online?.Node != null) { - //ts.Add(_starFactory.SendNodeCommand(online.Node.Code, "node/upgrade", null, 600, 0)); - var code = online.Node.Code; var cmd = new CommandModel { - //Code = online.Node.Code, Command = "node/upgrade", - Expire = DateTime.Now.AddSeconds(600), + Expire = DateTime.UtcNow.AddSeconds(600), }; - var queue = _deviceService.GetQueue(code); - queue.Add(cmd.ToJson()); + ts.Add(_deviceService.SendCommand(online.Node, cmd, HttpContext.RequestAborted)); } } @@ -105,20 +94,16 @@ public async Task Execute(String command, String argument) var ts = new List>(); foreach (var item in SelectKeys) { - var online = FindById(item.ToInt()); + var online = NodeOnline.FindById(item.ToInt()); if (online != null && online.Node != null) { - //ts.Add(_starFactory.SendNodeCommand(online.Node.Code, command, argument, 30, 0)); var cmd = new CommandModel { - //Code = online.Node.Code, Command = command, Argument = argument, - Expire = DateTime.Now.AddSeconds(30), + Expire = DateTime.UtcNow.AddSeconds(30), }; - var queue = _deviceService.GetQueue(online.Node.Code); - queue.Add(cmd.ToJson()); - ts.Add(Task.FromResult(1)); + ts.Add(_deviceService.SendCommand(online.Node, cmd, HttpContext.RequestAborted)); } } diff --git a/Zero.Web/Services/NodeService.cs b/Zero.Web/Services/NodeService.cs index 4a0cbe8..fab911b 100644 --- a/Zero.Web/Services/NodeService.cs +++ b/Zero.Web/Services/NodeService.cs @@ -1,12 +1,12 @@ using System.Reflection; using NewLife; using NewLife.Caching; -using NewLife.Caching.Queues; using NewLife.Log; using NewLife.Remoting; using NewLife.Remoting.Extensions.Models; using NewLife.Remoting.Extensions.Services; using NewLife.Remoting.Models; +using NewLife.Remoting.Services; using NewLife.Security; using NewLife.Serialization; using NewLife.Web; @@ -21,6 +21,7 @@ public class NodeService : IDeviceService { private readonly ICacheProvider _cacheProvider; private readonly ICache _cache; + private readonly ISessionManager _sessionManager; private readonly IPasswordProvider _passwordProvider; private readonly ITokenSetting _setting; private readonly ITracer _tracer; @@ -32,8 +33,9 @@ public class NodeService : IDeviceService /// /// /// - public NodeService(IPasswordProvider passwordProvider, ICacheProvider cacheProvider, ITokenSetting setting, ITracer tracer) + public NodeService(ISessionManager sessionManager, IPasswordProvider passwordProvider, ICacheProvider cacheProvider, ITokenSetting setting, ITracer tracer) { + _sessionManager = sessionManager; _passwordProvider = passwordProvider; _cacheProvider = cacheProvider; _cache = cacheProvider.InnerCache; @@ -84,7 +86,7 @@ public NodeService(IPasswordProvider passwordProvider, ICacheProvider cacheProvi } } - if (node == null) throw new ApiException(ApiCode.Unauthorized, "节点鉴权失败"); + if (node == null) throw new ApiException(ApiCode.Unauthorized, "登录失败"); node.Login(inf, ip); @@ -93,7 +95,7 @@ public NodeService(IPasswordProvider passwordProvider, ICacheProvider cacheProvi olt.Save(inf, null, null, ip); // 登录历史 - WriteHistory(node, source + "节点鉴权", true, $"[{node.Name}/{node.Code}]鉴权成功 " + inf.ToJson(false, false, false), ip); + WriteHistory(node, source + "登录", true, $"[{node.Name}/{node.Code}]登录成功 " + inf.ToJson(false, false, false), ip); var rs = new LoginResponse { @@ -282,18 +284,11 @@ public Int32 RemoveOnline(Int32 deviceId, String ip) #endregion #region 下行通知 - /// - /// 获取指定设备的命令队列 - /// - /// + /// 发送命令 + /// + /// /// - public IProducerConsumer GetQueue(String deviceCode) - { - var q = _cacheProvider.GetQueue($"cmd:{deviceCode}"); - if (q is QueueBase qb) qb.TraceName = "ServiceQueue"; - - return q; - } + public Task SendCommand(IDeviceModel device, CommandModel command, CancellationToken cancellationToken) => _sessionManager.PublishAsync(device.Code, command, null, cancellationToken); #endregion #region 升级更新 diff --git a/Zero.Web/Zero.Web.csproj b/Zero.Web/Zero.Web.csproj index c5a07dd..fa5c0d4 100644 --- a/Zero.Web/Zero.Web.csproj +++ b/Zero.Web/Zero.Web.csproj @@ -19,11 +19,11 @@ - - - - - + + + + + diff --git a/Zero.WebApi/Areas/Nodes/Controllers/NodeOnlineController.cs b/Zero.WebApi/Areas/Nodes/Controllers/NodeOnlineController.cs index 7f8e105..17cfa47 100644 --- a/Zero.WebApi/Areas/Nodes/Controllers/NodeOnlineController.cs +++ b/Zero.WebApi/Areas/Nodes/Controllers/NodeOnlineController.cs @@ -1,53 +1,113 @@ -using Zero.Data.Nodes; +using System.ComponentModel; using NewLife; using NewLife.Cube; -using NewLife.Cube.Extensions; -using NewLife.Cube.ViewModels; +using NewLife.Remoting.Extensions.Services; +using NewLife.Remoting.Models; using NewLife.Web; using XCode.Membership; +using Zero.Data.Nodes; -namespace Zero.Web.Areas.Nodes.Controllers +namespace Zero.Web.Areas.Nodes.Controllers; + +/// 节点在线 +[Menu(20, true, Icon = "fa-table")] +[NodesArea] +public class NodeOnlineController : EntityController { - /// 节点在线 - [Menu(20, true, Icon = "fa-table")] - [NodesArea] - public class NodeOnlineController : EntityController + private readonly IDeviceService _deviceService; + + static NodeOnlineController() + { + //LogOnChange = true; + + //ListFields.RemoveField("Id", "Creator"); + ListFields.RemoveCreateField(); + + //{ + // var df = ListFields.GetField("Code") as ListField; + // df.Url = "?code={Code}"; + //} + //{ + // var df = ListFields.AddListField("devices", null, "Onlines"); + // df.DisplayName = "查看设备"; + // df.Url = "Device?groupId={Id}"; + // df.DataVisible = e => (e as NodeOnline).Devices > 0; + //} + //{ + // var df = ListFields.GetField("Kind") as ListField; + // df.GetValue = e => ((Int32)(e as NodeOnline).Kind).ToString("X4"); + //} + //ListFields.TraceUrl("TraceId"); + } + + public NodeOnlineController(IDeviceService deviceService) => _deviceService = deviceService; + + /// 高级搜索。列表页查询、导出Excel、导出Json、分享页等使用 + /// 分页器。包含分页排序参数,以及Http请求参数 + /// + protected override IEnumerable Search(Pager p) + { + var nodeId = p["nodeId"].ToInt(-1); + var rids = p["areaId"].SplitAsInt("/"); + var provinceId = rids.Length > 0 ? rids[0] : -1; + var cityId = rids.Length > 1 ? rids[1] : -1; + var category = p["category"]; + + var start = p["dtStart"].ToDateTime(); + var end = p["dtEnd"].ToDateTime(); + + return NodeOnline.Search(nodeId, provinceId, cityId, category, start, end, p["Q"], p); + } + + [DisplayName("检查更新")] + [EntityAuthorize((PermissionFlags)16)] + public async Task CheckUpgrade() { - static NodeOnlineController() + var ts = new List(); + foreach (var item in SelectKeys) { - //LogOnChange = true; - - //ListFields.RemoveField("Id", "Creator"); - ListFields.RemoveCreateField(); - - //{ - // var df = ListFields.GetField("Code") as ListField; - // df.Url = "?code={Code}"; - //} - //{ - // var df = ListFields.AddListField("devices", null, "Onlines"); - // df.DisplayName = "查看设备"; - // df.Url = "Device?groupId={Id}"; - // df.DataVisible = e => (e as NodeOnline).Devices > 0; - //} - //{ - // var df = ListFields.GetField("Kind") as ListField; - // df.GetValue = e => ((Int32)(e as NodeOnline).Kind).ToString("X4"); - //} - //ListFields.TraceUrl("TraceId"); + var online = NodeOnline.FindById(item.ToInt()); + if (online?.Node != null) + { + var cmd = new CommandModel + { + Command = "node/upgrade", + Expire = DateTime.UtcNow.AddSeconds(600), + }; + ts.Add(_deviceService.SendCommand(online.Node, cmd, HttpContext.RequestAborted)); + } } - /// 高级搜索。列表页查询、导出Excel、导出Json、分享页等使用 - /// 分页器。包含分页排序参数,以及Http请求参数 - /// - protected override IEnumerable Search(Pager p) - { - //var deviceId = p["deviceId"].ToInt(-1); + await Task.WhenAll(ts); + + return "操作成功!"; + } - var start = p["dtStart"].ToDateTime(); - var end = p["dtEnd"].ToDateTime(); + [DisplayName("执行命令")] + [EntityAuthorize((PermissionFlags)16)] + public async Task Execute(String command, String argument) + { + if (GetRequest("keys") == null) throw new ArgumentNullException(nameof(SelectKeys)); + if (command.IsNullOrEmpty()) throw new ArgumentNullException(nameof(command)); - return NodeOnline.Search(start, end, p["Q"], p); + var ts = new List>(); + foreach (var item in SelectKeys) + { + var online = NodeOnline.FindById(item.ToInt()); + if (online != null && online.Node != null) + { + var cmd = new CommandModel + { + Command = command, + Argument = argument, + Expire = DateTime.UtcNow.AddSeconds(30), + }; + ts.Add(_deviceService.SendCommand(online.Node, cmd, HttpContext.RequestAborted)); + } } + + var rs = await Task.WhenAll(ts); + + return $"操作成功!下发指令{rs.Length}个,成功{rs.Count(e => e > 0)}个"; } } \ No newline at end of file diff --git a/Zero.WebApi/Services/NodeService.cs b/Zero.WebApi/Services/NodeService.cs index 6b201a5..8398f0f 100644 --- a/Zero.WebApi/Services/NodeService.cs +++ b/Zero.WebApi/Services/NodeService.cs @@ -1,12 +1,12 @@ using System.Reflection; using NewLife; using NewLife.Caching; -using NewLife.Caching.Queues; using NewLife.Log; using NewLife.Remoting; using NewLife.Remoting.Extensions.Models; using NewLife.Remoting.Extensions.Services; using NewLife.Remoting.Models; +using NewLife.Remoting.Services; using NewLife.Security; using NewLife.Serialization; using NewLife.Web; @@ -21,6 +21,7 @@ public class NodeService : IDeviceService { private readonly ICacheProvider _cacheProvider; private readonly ICache _cache; + private readonly ISessionManager _sessionManager; private readonly IPasswordProvider _passwordProvider; private readonly ITokenSetting _setting; private readonly ITracer _tracer; @@ -32,8 +33,9 @@ public class NodeService : IDeviceService /// /// /// - public NodeService(IPasswordProvider passwordProvider, ICacheProvider cacheProvider, ITokenSetting setting, ITracer tracer) + public NodeService(ISessionManager sessionManager, IPasswordProvider passwordProvider, ICacheProvider cacheProvider, ITokenSetting setting, ITracer tracer) { + _sessionManager = sessionManager; _passwordProvider = passwordProvider; _cacheProvider = cacheProvider; _cache = cacheProvider.InnerCache; @@ -84,7 +86,7 @@ public NodeService(IPasswordProvider passwordProvider, ICacheProvider cacheProvi } } - if (node == null) throw new ApiException(ApiCode.Unauthorized, "节点鉴权失败"); + if (node == null) throw new ApiException(ApiCode.Unauthorized, "登录失败"); node.Login(inf, ip); @@ -93,7 +95,7 @@ public NodeService(IPasswordProvider passwordProvider, ICacheProvider cacheProvi olt.Save(inf, null, null, ip); // 登录历史 - WriteHistory(node, source + "节点鉴权", true, $"[{node.Name}/{node.Code}]鉴权成功 " + inf.ToJson(false, false, false), ip); + WriteHistory(node, source + "登录", true, $"[{node.Name}/{node.Code}]登录成功 " + inf.ToJson(false, false, false), ip); var rs = new LoginResponse { @@ -282,18 +284,11 @@ public Int32 RemoveOnline(Int32 deviceId, String ip) #endregion #region 下行通知 - /// - /// 获取指定设备的命令队列 - /// - /// + /// 发送命令 + /// + /// /// - public IProducerConsumer GetQueue(String deviceCode) - { - var q = _cacheProvider.GetQueue($"cmd:{deviceCode}"); - if (q is QueueBase qb) qb.TraceName = "ServiceQueue"; - - return q; - } + public Task SendCommand(IDeviceModel device, CommandModel command, CancellationToken cancellationToken) => _sessionManager.PublishAsync(device.Code, command, null, cancellationToken); #endregion #region 升级更新 diff --git a/Zero.WebApi/Zero.WebApi.csproj b/Zero.WebApi/Zero.WebApi.csproj index 2abf78a..f609216 100644 --- a/Zero.WebApi/Zero.WebApi.csproj +++ b/Zero.WebApi/Zero.WebApi.csproj @@ -32,13 +32,13 @@ - - - + + + - - - + + + diff --git a/Zero.WebSocketServer/Zero.WebSocketServer.csproj b/Zero.WebSocketServer/Zero.WebSocketServer.csproj index cc88f70..df72405 100644 --- a/Zero.WebSocketServer/Zero.WebSocketServer.csproj +++ b/Zero.WebSocketServer/Zero.WebSocketServer.csproj @@ -21,10 +21,10 @@ - - - - + + + + diff --git a/Zero.WebView/Zero.WebView.csproj b/Zero.WebView/Zero.WebView.csproj index 8bcfa5d..f8e6975 100644 --- a/Zero.WebView/Zero.WebView.csproj +++ b/Zero.WebView/Zero.WebView.csproj @@ -27,9 +27,9 @@ - - - + + + diff --git a/Zero.Worker/Zero.Worker.csproj b/Zero.Worker/Zero.Worker.csproj index c753be1..6c3d3f3 100644 --- a/Zero.Worker/Zero.Worker.csproj +++ b/Zero.Worker/Zero.Worker.csproj @@ -19,12 +19,12 @@ - - - - - + + + + + - +