diff --git a/NewLife.Remoting.Extensions/Controllers/BaseDeviceController.cs b/NewLife.Remoting.Extensions/Controllers/BaseDeviceController.cs
index 98ed9d2..2a14817 100644
--- a/NewLife.Remoting.Extensions/Controllers/BaseDeviceController.cs
+++ b/NewLife.Remoting.Extensions/Controllers/BaseDeviceController.cs
@@ -182,13 +182,18 @@ public class BaseDeviceController : BaseController
{
using var socket = await HttpContext.WebSockets.AcceptWebSocketAsync();
- await Handle(socket, Token);
+ await HandleNotify(socket, Token);
}
else
HttpContext.Response.StatusCode = 400;
}
- private async Task Handle(WebSocket socket, String token)
+ /// <summary>处理长连接</summary>
+ /// <param name="socket"></param>
+ /// <param name="token"></param>
+ /// <returns></returns>
+ /// <exception cref="InvalidOperationException"></exception>
+ protected virtual async Task HandleNotify(WebSocket socket, String token)
{
var device = _device ?? throw new InvalidOperationException("未登录!");
diff --git a/NewLife.Remoting/Clients/ClientBase.cs b/NewLife.Remoting/Clients/ClientBase.cs
index faa215b..fbda299 100644
--- a/NewLife.Remoting/Clients/ClientBase.cs
+++ b/NewLife.Remoting/Clients/ClientBase.cs
@@ -477,6 +477,10 @@ public abstract class ClientBase : DisposeBase, IApiClient, ICommandClient, IEve
info.Compile = asm.Compile.ToUniversalTime().ToLong();
}
+ info.IP = NetHelper.GetIPsWithCache().Where(e => e.IsIPv4() && e.GetAddressBytes()[0] != 169).Join();
+ info.Macs = NetHelper.GetMacs().Select(e => e.ToHex("-")).Where(e => e != "00-00-00-00-00-00").OrderBy(e => e).Join(",");
+ info.UUID = MachineInfo.GetCurrent().BuildCode();
+
info.Time = DateTime.UtcNow.ToLong();
}
}
diff --git a/NewLife.Remoting/Models/LoginRequest.cs b/NewLife.Remoting/Models/LoginRequest.cs
index c0eecf8..dcf4a1e 100644
--- a/NewLife.Remoting/Models/LoginRequest.cs
+++ b/NewLife.Remoting/Models/LoginRequest.cs
@@ -38,6 +38,15 @@ public class LoginRequest : ILoginRequest
/// <summary>编译时间。UTC毫秒</summary>
public Int64 Compile { get; set; }
+ /// <summary>本地IP地址</summary>
+ public String? IP { get; set; }
+
+ /// <summary>MAC地址</summary>
+ public String? Macs { get; set; }
+
+ /// <summary>唯一标识</summary>
+ public String? UUID { get; set; }
+
/// <summary>本地时间。UTC毫秒</summary>
public Int64 Time { get; set; }
#endregion
diff --git a/NewLife.Remoting/Models/PingRequest.cs b/NewLife.Remoting/Models/PingRequest.cs
index 17a8e94..9f2b6d7 100644
--- a/NewLife.Remoting/Models/PingRequest.cs
+++ b/NewLife.Remoting/Models/PingRequest.cs
@@ -38,8 +38,8 @@ public class PingRequest : IPingRequest
/// <summary>电量</summary>
public Double Battery { get; set; }
- ///// <summary>信号强度。WiFi/4G</summary>
- //public Int32 Signal { get; set; }
+ /// <summary>信号强度。WiFi/4G</summary>
+ public Int32 Signal { get; set; }
/// <summary>上行速度。网络发送速度,字节每秒</summary>
public UInt64 UplinkSpeed { get; set; }
diff --git a/Samples/IoTZero/Clients/HttpDevice.cs b/Samples/IoTZero/Clients/HttpDevice.cs
index 6864337..37ba972 100644
--- a/Samples/IoTZero/Clients/HttpDevice.cs
+++ b/Samples/IoTZero/Clients/HttpDevice.cs
@@ -1,7 +1,6 @@
using NewLife;
using NewLife.IoT.Models;
using NewLife.IoT.ThingModels;
-using NewLife.Log;
using NewLife.Model;
using NewLife.Remoting;
using NewLife.Remoting.Clients;
@@ -64,15 +63,12 @@ public class HttpDevice : ClientBase
#region 登录
public override ILoginRequest BuildLoginRequest()
{
- var request = base.BuildLoginRequest();
- if (request is LoginInfo info)
- {
- info.ProductKey = ProductKey;
- info.ProductSecret = ProductSecret;
- info.Name = Environment.MachineName;
- info.IP = NetHelper.MyIP() + "";
- info.UUID = MachineInfo.GetCurrent().BuildCode();
- }
+ var request = new LoginInfo();
+ FillLoginRequest(request);
+
+ request.ProductKey = ProductKey;
+ request.ProductSecret = ProductSecret;
+ request.Name = Environment.MachineName;
return request;
}
@@ -81,12 +77,8 @@ public class HttpDevice : ClientBase
#region 心跳
public override IPingRequest BuildPingRequest()
{
- var request = base.BuildPingRequest();
- if (request is PingInfo info)
- {
- info.Memory = 0;
- info.TotalSize = 0;
- }
+ var request = new PingInfo();
+ FillPingRequest(request);
return request;
}
diff --git a/Samples/IoTZero/Models/LoginInfo.cs b/Samples/IoTZero/Models/LoginInfo.cs
index f42973a..26b25cb 100644
--- a/Samples/IoTZero/Models/LoginInfo.cs
+++ b/Samples/IoTZero/Models/LoginInfo.cs
@@ -27,11 +27,11 @@ public class LoginInfo : LoginRequest
///// <summary>版本</summary>
//public String Version { get; set; }
- /// <summary>本地IP地址</summary>
- public String IP { get; set; }
+ ///// <summary>本地IP地址</summary>
+ //public String IP { get; set; }
- /// <summary>唯一标识</summary>
- public String UUID { get; set; }
+ ///// <summary>唯一标识</summary>
+ //public String UUID { get; set; }
///// <summary>本地UTC时间</summary>
//public Int64 Time { get; set; }
diff --git a/Samples/IoTZero/Models/PingInfo.cs b/Samples/IoTZero/Models/PingInfo.cs
index 04ebe73..9b2c1a8 100644
--- a/Samples/IoTZero/Models/PingInfo.cs
+++ b/Samples/IoTZero/Models/PingInfo.cs
@@ -6,14 +6,14 @@ namespace NewLife.IoT.Models;
public class PingInfo : PingRequest
{
#region 属性
- /// <summary>内存大小</summary>
- public UInt64 Memory { get; set; }
+ ///// <summary>内存大小</summary>
+ //public UInt64 Memory { get; set; }
///// <summary>可用内存大小</summary>
//public UInt64 AvailableMemory { get; set; }
- /// <summary>磁盘大小。应用所在盘</summary>
- public UInt64 TotalSize { get; set; }
+ ///// <summary>磁盘大小。应用所在盘</summary>
+ //public UInt64 TotalSize { get; set; }
///// <summary>磁盘可用空间。应用所在盘</summary>
//public UInt64 AvailableFreeSpace { get; set; }
diff --git a/Samples/ZeroServer/appsettings.json b/Samples/ZeroServer/appsettings.json
index 4898adc..1338702 100644
--- a/Samples/ZeroServer/appsettings.json
+++ b/Samples/ZeroServer/appsettings.json
@@ -7,7 +7,7 @@
}
},
"AllowedHosts": "*",
- "Urls": "http://*:1880",
+ "Urls": "http://*:6080",
"ConnectionStrings": {
"IoT": "Data Source=..\\Data\\IoT.db;Provider=Sqlite",
"IoTData": "Data Source=..\\Data\\IoTData.db;ShowSql=false;Provider=Sqlite",
diff --git a/Samples/ZeroServer/Clients/ClientSetting.cs b/Samples/ZeroServer/Clients/ClientSetting.cs
index 5fd18c3..5dce91e 100644
--- a/Samples/ZeroServer/Clients/ClientSetting.cs
+++ b/Samples/ZeroServer/Clients/ClientSetting.cs
@@ -11,7 +11,7 @@ public class ClientSetting : Config<ClientSetting>, IClientSetting
#region 属性
/// <summary>服务端地址。IoT服务平台地址</summary>
[Description("服务端地址。IoT服务平台地址")]
- public String Server { get; set; } = "http://localhost:2880";
+ public String Server { get; set; } = "http://localhost:6080";
/// <summary>客户端编码</summary>
[Description("客户端编码")]
diff --git a/Samples/ZeroServer/Clients/ClientTest.cs b/Samples/ZeroServer/Clients/ClientTest.cs
index e3aa12d..f908441 100644
--- a/Samples/ZeroServer/Clients/ClientTest.cs
+++ b/Samples/ZeroServer/Clients/ClientTest.cs
@@ -1,12 +1,12 @@
using NewLife.Log;
-namespace ZeroClient.Clients;
+namespace ZeroClient;
/// <summary>客户端测试入口。主程序通过反射调用</summary>
public static class ClientTest
{
private static ITracer _tracer;
- private static HttpDevice _device;
+ private static NodeClient _device;
public static async Task Main(IServiceProvider serviceProvider)
{
@@ -19,7 +19,7 @@ public static class ClientTest
var set = ClientSetting.Current;
// 产品编码、产品密钥从IoT管理平台获取,设备编码支持自动注册
- var device = new HttpDevice(set)
+ var device = new NodeClient(set)
{
Tracer = _tracer,
Log = XTrace.Log,
diff --git a/Samples/ZeroServer/Clients/HttpDevice.cs b/Samples/ZeroServer/Clients/NodeClient.cs
similarity index 64%
rename from Samples/ZeroServer/Clients/HttpDevice.cs
rename to Samples/ZeroServer/Clients/NodeClient.cs
index 5893244..3cc81a9 100644
--- a/Samples/ZeroServer/Clients/HttpDevice.cs
+++ b/Samples/ZeroServer/Clients/NodeClient.cs
@@ -1,23 +1,28 @@
using NewLife;
-using NewLife.IoT.Models;
-using NewLife.IoT.ThingModels;
using NewLife.Model;
-using NewLife.Remoting;
using NewLife.Remoting.Clients;
using NewLife.Remoting.Models;
using NewLife.Security;
+using ZeroServer.Models;
+using MigrationEventArgs = Stardust.Models.MigrationEventArgs;
namespace ZeroClient;
/// <summary>Http协议设备</summary>
-public class HttpDevice : ClientBase
+public class NodeClient : ClientBase
{
#region 属性
+ /// <summary>产品编码</summary>
+ public String? ProductCode { get; set; }
+
+ /// <summary>服务迁移</summary>
+ public event EventHandler<MigrationEventArgs>? OnMigration;
+
private readonly ClientSetting _setting;
#endregion
#region 构造
- public HttpDevice(ClientSetting setting) : base(setting)
+ public NodeClient(ClientSetting setting) : base(setting)
{
// 设置动作,开启下行通知
Features = Features.Login | Features.Logout | Features.Ping | Features.Notify | Features.Upgrade;
@@ -49,13 +54,11 @@ public class HttpDevice : ClientBase
#region 登录
public override ILoginRequest BuildLoginRequest()
{
- var request = base.BuildLoginRequest();
- if (request is LoginInfo info)
- {
- info.Name = Environment.MachineName;
- info.IP = NetHelper.MyIP() + "";
- info.UUID = MachineInfo.GetCurrent().BuildCode();
- }
+ var request = new LoginInfo();
+ FillLoginRequest(request);
+
+ request.ProductCode = ProductCode;
+ request.Name = Environment.MachineName;
return request;
}
@@ -64,46 +67,39 @@ public class HttpDevice : ClientBase
#region 心跳
public override IPingRequest BuildPingRequest()
{
- var request = base.BuildPingRequest();
- if (request is PingInfo info)
- {
- info.Memory = 0;
- info.TotalSize = 0;
- }
+ var request = new PingInfo();
+ FillPingRequest(request);
return request;
}
- #endregion
- #region 数据
- /// <summary>上传数据</summary>
+ /// <summary>心跳</summary>
/// <returns></returns>
- public async Task PostDataAsync()
+ public override async Task<IPingResponse?> Ping(CancellationToken cancellationToken = default)
{
- //if (Tracer != null) DefaultSpan.Current = null;
-
- using var span = Tracer?.NewSpan("PostData");
- try
+ var rs = await base.Ping(cancellationToken);
+ if (rs != null)
{
- var items = new List<DataModel>
+ // 迁移到新服务器
+ if (rs is PingResponse prs && !prs.NewServer.IsNullOrEmpty() && prs.NewServer != Server)
{
- new() {
- Time = DateTime.UtcNow.ToLong(),
- Name = "TestValue",
- Value = Rand.Next(0, 100) + ""
- }
- };
+ var arg = new MigrationEventArgs { NewServer = prs.NewServer };
- var data = new DataModels { DeviceCode = Code, Items = items.ToArray() };
+ OnMigration?.Invoke(this, arg);
+ if (!arg.Cancel)
+ {
+ await Logout("切换新服务器");
- await InvokeAsync<Int32>("Thing/PostData", data);
- }
- catch (Exception ex)
- {
- span?.SetError(ex, null);
+ // 清空原有链接,添加新链接
+ Server = prs.NewServer;
+ Client = null;
- throw;
+ await Login();
+ }
+ }
}
+
+ return rs;
}
#endregion
}
\ No newline at end of file
diff --git a/Samples/ZeroServer/Controllers/NodeController.cs b/Samples/ZeroServer/Controllers/NodeController.cs
index d4728f0..982dee1 100644
--- a/Samples/ZeroServer/Controllers/NodeController.cs
+++ b/Samples/ZeroServer/Controllers/NodeController.cs
@@ -1,9 +1,12 @@
-using Microsoft.AspNetCore.Mvc;
+using System.Net.WebSockets;
+using Microsoft.AspNetCore.Mvc;
using NewLife.Log;
using NewLife.Remoting;
using NewLife.Remoting.Extensions;
+using NewLife.Remoting.Extensions.Services;
using NewLife.Remoting.Models;
using Zero.Data.Nodes;
+using ZeroServer.Services;
namespace ZeroServer.Controllers;
@@ -14,8 +17,9 @@ namespace ZeroServer.Controllers;
public class NodeController : BaseDeviceController
{
/// <summary>当前设备</summary>
- public Node Node { get; set; }
+ public Node? Node { get; set; }
+ private readonly NodeService _nodeService;
private readonly ITracer _tracer;
#region 构造
@@ -27,6 +31,7 @@ public class NodeController : BaseDeviceController
/// <param name="tracer"></param>
public NodeController(IServiceProvider serviceProvider, ITracer tracer) : base(serviceProvider)
{
+ _nodeService = serviceProvider.GetRequiredService<IDeviceService>() as NodeService;
_tracer = tracer;
}
@@ -44,15 +49,43 @@ public class NodeController : BaseDeviceController
/// <summary>心跳</summary>
/// <param name="request"></param>
/// <returns></returns>
- protected override IPingResponse OnPing(IPingRequest request)
+ protected override IPingResponse OnPing(IPingRequest? request)
{
var rs = base.OnPing(request);
var device = Node;
- if (device != null && rs != null)
+ if (device != null)
rs.Period = device.Period;
return rs;
}
+
+ protected override async Task HandleNotify(WebSocket socket, String token)
+ {
+ NodeOnline online = null;
+ var node = Node;
+ if (node != null)
+ {
+ online = _nodeService.GetOnline(node, UserHost);
+ if (online != null)
+ {
+ online.WebSocket = true;
+ online.Update();
+ }
+ }
+
+ try
+ {
+ await base.HandleNotify(socket, token);
+ }
+ finally
+ {
+ if (online != null)
+ {
+ online.WebSocket = false;
+ online.Update();
+ }
+ }
+ }
#endregion
}
\ No newline at end of file
diff --git a/Samples/ZeroServer/Models/LoginInfo.cs b/Samples/ZeroServer/Models/LoginInfo.cs
index f42973a..d4cb36b 100644
--- a/Samples/ZeroServer/Models/LoginInfo.cs
+++ b/Samples/ZeroServer/Models/LoginInfo.cs
@@ -1,39 +1,39 @@
using NewLife.Remoting.Models;
-namespace NewLife.IoT.Models;
+namespace ZeroServer.Models;
/// <summary>节点登录信息</summary>
public class LoginInfo : LoginRequest
{
#region 属性
- ///// <summary>设备编码</summary>
- //public String Code { get; set; }
+ /// <summary>产品编码</summary>
+ public String? ProductCode { get; set; }
- ///// <summary>设备密钥</summary>
- //public String Secret { get; set; }
+ /// <summary>名称。可用于标识设备的名称</summary>
+ public String? Name { get; set; }
- /// <summary>产品证书</summary>
- public String ProductKey { get; set; }
+ /// <summary>系统名</summary>
+ public String? OSName { get; set; }
- /// <summary>产品密钥</summary>
- public String ProductSecret { get; set; }
+ /// <summary>系统版本</summary>
+ public String? OSVersion { get; set; }
- ///// <summary>实例。应用可能多实例部署,ip@proccessid</summary>
- //public String ClientId { get; set; }
+ /// <summary>处理器架构</summary>
+ public String? Architecture { get; set; }
- /// <summary>名称。可用于标识设备的名称</summary>
- public String Name { get; set; }
+ /// <summary>机器名</summary>
+ public String? MachineName { get; set; }
- ///// <summary>版本</summary>
- //public String Version { get; set; }
+ /// <summary>用户名</summary>
+ public String? UserName { get; set; }
- /// <summary>本地IP地址</summary>
- public String IP { get; set; }
+ /// <summary>核心数</summary>
+ public Int32 ProcessorCount { get; set; }
- /// <summary>唯一标识</summary>
- public String UUID { get; set; }
+ /// <summary>内存大小</summary>
+ public UInt64 Memory { get; set; }
- ///// <summary>本地UTC时间</summary>
- //public Int64 Time { get; set; }
+ /// <summary>磁盘大小。应用所在盘</summary>
+ public UInt64 TotalSize { get; set; }
#endregion
}
\ No newline at end of file
diff --git a/Samples/ZeroServer/Models/PingInfo.cs b/Samples/ZeroServer/Models/PingInfo.cs
index 04ebe73..e67a364 100644
--- a/Samples/ZeroServer/Models/PingInfo.cs
+++ b/Samples/ZeroServer/Models/PingInfo.cs
@@ -1,19 +1,19 @@
using NewLife.Remoting.Models;
-namespace NewLife.IoT.Models;
+namespace ZeroServer.Models;
/// <summary>心跳信息</summary>
public class PingInfo : PingRequest
{
#region 属性
- /// <summary>内存大小</summary>
- public UInt64 Memory { get; set; }
+ ///// <summary>内存大小</summary>
+ //public UInt64 Memory { get; set; }
///// <summary>可用内存大小</summary>
//public UInt64 AvailableMemory { get; set; }
- /// <summary>磁盘大小。应用所在盘</summary>
- public UInt64 TotalSize { get; set; }
+ ///// <summary>磁盘大小。应用所在盘</summary>
+ //public UInt64 TotalSize { get; set; }
///// <summary>磁盘可用空间。应用所在盘</summary>
//public UInt64 AvailableFreeSpace { get; set; }
diff --git "a/Samples/ZeroServer/Nodes/\350\212\202\347\202\271.Biz.cs" "b/Samples/ZeroServer/Nodes/\350\212\202\347\202\271.Biz.cs"
index 4e15d59..ceec499 100644
--- "a/Samples/ZeroServer/Nodes/\350\212\202\347\202\271.Biz.cs"
+++ "b/Samples/ZeroServer/Nodes/\350\212\202\347\202\271.Biz.cs"
@@ -4,10 +4,10 @@ using System.Xml.Serialization;
using NewLife;
using NewLife.Data;
using NewLife.Remoting.Models;
-using Stardust.Models;
using XCode;
using XCode.Cache;
using XCode.Membership;
+using ZeroServer.Models;
namespace Zero.Data.Nodes;
@@ -386,7 +386,7 @@ public partial class Node : Entity<Node>, IDeviceModel
/// <summary>登录并保存信息</summary>
/// <param name="di"></param>
/// <param name="ip"></param>
- public void Login(NodeInfo di, String ip)
+ public void Login(LoginInfo di, String ip)
{
var node = this;
@@ -410,7 +410,7 @@ public partial class Node : Entity<Node>, IDeviceModel
/// <summary>填充</summary>
/// <param name="di"></param>
- public void Fill(NodeInfo di)
+ public void Fill(LoginInfo di)
{
var node = this;
@@ -418,28 +418,17 @@ public partial class Node : Entity<Node>, IDeviceModel
if (!di.OSVersion.IsNullOrEmpty()) node.OSVersion = di.OSVersion;
if (!di.Architecture.IsNullOrEmpty()) node.Architecture = di.Architecture;
if (!di.Version.IsNullOrEmpty()) node.Version = di.Version;
- if (di.Compile.Year > 2000) node.CompileTime = di.Compile;
+ if (di.Compile > 2000) node.CompileTime = di.Compile.ToDateTime().ToLocalTime();
if (!di.MachineName.IsNullOrEmpty()) node.MachineName = di.MachineName;
if (!di.UserName.IsNullOrEmpty()) node.UserName = di.UserName;
if (!di.IP.IsNullOrEmpty()) node.IP = di.IP;
- if (!di.Processor.IsNullOrEmpty()) node.Processor = di.Processor;
- //if (!di.CpuID.IsNullOrEmpty()) node.CpuID = di.CpuID;
if (!di.UUID.IsNullOrEmpty()) node.Uuid = di.UUID;
- if (!di.MachineGuid.IsNullOrEmpty()) node.MachineGuid = di.MachineGuid;
- if (!di.DiskID.IsNullOrEmpty()) node.DiskID = di.DiskID;
if (di.ProcessorCount > 0) node.Cpu = di.ProcessorCount;
if (di.Memory > 0) node.Memory = (Int32)(di.Memory / 1024 / 1024);
if (di.TotalSize > 0) node.TotalSize = (Int32)(di.TotalSize / 1024 / 1024);
- if (di.MaxOpenFiles > 0) node.MaxOpenFiles = di.MaxOpenFiles;
- if (!di.Dpi.IsNullOrEmpty()) node.Dpi = di.Dpi;
- if (!di.Resolution.IsNullOrEmpty()) node.Resolution = di.Resolution;
if (!di.Macs.IsNullOrEmpty()) node.MACs = di.Macs;
- //if (!di.COMs.IsNullOrEmpty()) node.COMs = di.COMs;
- if (!di.InstallPath.IsNullOrEmpty()) node.InstallPath = di.InstallPath;
- if (!di.Runtime.IsNullOrEmpty()) node.Runtime = di.Runtime;
- if (!di.Framework.IsNullOrEmpty()) node.Framework = di.Framework;
}
/// <summary>修正地区</summary>
diff --git "a/Samples/ZeroServer/Nodes/\350\212\202\347\202\271\345\216\206\345\217\262.Biz.cs" "b/Samples/ZeroServer/Nodes/\350\212\202\347\202\271\345\216\206\345\217\262.Biz.cs"
index 78ca684..6ed27eb 100644
--- "a/Samples/ZeroServer/Nodes/\350\212\202\347\202\271\345\216\206\345\217\262.Biz.cs"
+++ "b/Samples/ZeroServer/Nodes/\350\212\202\347\202\271\345\216\206\345\217\262.Biz.cs"
@@ -19,6 +19,7 @@ public partial class NodeHistory : Entity<NodeHistory>
Meta.Modules.Add<TimeModule>();
Meta.Modules.Add<IPModule>();
+ Meta.Modules.Add<TraceModule>();
}
/// <summary>插入或修改时</summary>
@@ -79,34 +80,34 @@ public partial class NodeHistory : Entity<NodeHistory>
return Find(_.Id == id);
}
-/// <summary>根据编号查找</summary>
-/// <param name="id">编号</param>
-/// <returns>实体对象</returns>
-public static NodeHistory FindById(Int64 id)
-{
- if (id <= 0) return null;
+ /// <summary>根据编号查找</summary>
+ /// <param name="id">编号</param>
+ /// <returns>实体对象</returns>
+ public static NodeHistory FindById(Int64 id)
+ {
+ if (id <= 0) return null;
- // 实体缓存
- if (Meta.Session.Count < 1000) return Meta.Cache.Find(e => e.Id == id);
+ // 实体缓存
+ if (Meta.Session.Count < 1000) return Meta.Cache.Find(e => e.Id == id);
- // 单对象缓存
- return Meta.SingleCache[id];
+ // 单对象缓存
+ return Meta.SingleCache[id];
- //return Find(_.Id == id);
-}
+ //return Find(_.Id == id);
+ }
-/// <summary>根据节点、操作查找</summary>
-/// <param name="nodeId">节点</param>
-/// <param name="action">操作</param>
-/// <returns>实体列表</returns>
-public static IList<NodeHistory> FindAllByNodeIDAndAction(Int32 nodeId, String action)
-{
+ /// <summary>根据节点、操作查找</summary>
+ /// <param name="nodeId">节点</param>
+ /// <param name="action">操作</param>
+ /// <returns>实体列表</returns>
+ public static IList<NodeHistory> FindAllByNodeIDAndAction(Int32 nodeId, String action)
+ {
- // 实体缓存
- if (Meta.Session.Count < 1000) return Meta.Cache.FindAll(e => e.NodeId == nodeId && e.Action.EqualIgnoreCase(action));
+ // 实体缓存
+ if (Meta.Session.Count < 1000) return Meta.Cache.FindAll(e => e.NodeId == nodeId && e.Action.EqualIgnoreCase(action));
- return FindAll(_.NodeId == nodeId & _.Action == action);
-}
+ return FindAll(_.NodeId == nodeId & _.Action == action);
+ }
#endregion
#region 高级查询
@@ -163,7 +164,7 @@ public static IList<NodeHistory> FindAllByNodeIDAndAction(Int32 nodeId, String a
/// <returns></returns>
public static NodeHistory Create(Node node, String action, Boolean success, String remark, String creator, String ip)
{
- if (node == null) node = new Node();
+ node ??= new Node();
var history = new NodeHistory
{
diff --git "a/Samples/ZeroServer/Nodes/\350\212\202\347\202\271\345\234\250\347\272\277.Biz.cs" "b/Samples/ZeroServer/Nodes/\350\212\202\347\202\271\345\234\250\347\272\277.Biz.cs"
index 0adaa36..7dd2313 100644
--- "a/Samples/ZeroServer/Nodes/\350\212\202\347\202\271\345\234\250\347\272\277.Biz.cs"
+++ "b/Samples/ZeroServer/Nodes/\350\212\202\347\202\271\345\234\250\347\272\277.Biz.cs"
@@ -5,9 +5,9 @@ using NewLife;
using NewLife.Data;
using NewLife.Remoting.Models;
using NewLife.Serialization;
-using Stardust.Models;
using XCode;
using XCode.Membership;
+using ZeroServer.Models;
namespace Zero.Data.Nodes;
@@ -193,90 +193,76 @@ public partial class NodeOnline : Entity<NodeOnline>, IOnlineModel
}
/// <summary>更新并保存在线状态</summary>
- /// <param name="di"></param>
- /// <param name="pi"></param>
+ /// <param name="login"></param>
+ /// <param name="ping"></param>
/// <param name="token"></param>
/// <param name="ip"></param>
- public void Save(NodeInfo di, PingInfo pi, String token, String ip)
+ public void Save(LoginInfo login, PingInfo ping, String token, String ip)
{
- var olt = this;
+ var online = this;
- if (di != null)
+ if (login != null)
{
- olt.Fill(di);
- olt.LocalTime = di.Time.ToLocalTime();
- olt.MACs = di.Macs;
- //olt.COMs = di.COMs;
+ online.Fill(login);
+ online.LocalTime = login.Time.ToDateTime().ToLocalTime();
+ online.MACs = login.Macs;
}
else
{
- olt.Fill(pi);
- //olt.CreateData(pi, ip);
+ online.Fill(ping);
}
- olt.Token = token;
- olt.PingCount++;
- olt.UpdateIP = ip;
+ online.Token = token;
+ online.PingCount++;
+ online.UpdateIP = ip;
// 5秒内直接保存
- if (olt.CreateTime.AddSeconds(5) > DateTime.Now)
- olt.Save();
+ if (online.CreateTime.AddSeconds(5) > DateTime.Now)
+ online.Save();
else
- olt.SaveAsync();
+ online.SaveAsync();
}
/// <summary>填充节点信息</summary>
/// <param name="di"></param>
- public void Fill(NodeInfo di)
+ public void Fill(LoginInfo di)
{
var online = this;
- online.LocalTime = di.Time.ToLocalTime();
+ online.LocalTime = di.Time.ToDateTime().ToLocalTime();
online.MACs = di.Macs;
//online.COMs = di.COMs;
online.IP = di.IP;
-
- if (di.AvailableMemory > 0) online.AvailableMemory = (Int32)(di.AvailableMemory / 1024 / 1024);
- if (di.AvailableFreeSpace > 0) online.AvailableFreeSpace = (Int32)(di.AvailableFreeSpace / 1024 / 1024);
}
/// <summary>填充在线节点信息</summary>
/// <param name="inf"></param>
private void Fill(PingInfo inf)
{
- var olt = this;
-
- if (inf.AvailableMemory > 0) olt.AvailableMemory = (Int32)(inf.AvailableMemory / 1024 / 1024);
- if (inf.AvailableFreeSpace > 0) olt.AvailableFreeSpace = (Int32)(inf.AvailableFreeSpace / 1024 / 1024);
- if (inf.CpuRate > 0) olt.CpuRate = inf.CpuRate;
- if (inf.Temperature > 0) olt.Temperature = inf.Temperature;
- if (inf.Battery > 0) olt.Battery = inf.Battery;
- if (inf.UplinkSpeed > 0) olt.UplinkSpeed = (Int64)inf.UplinkSpeed;
- if (inf.DownlinkSpeed > 0) olt.DownlinkSpeed = (Int64)inf.DownlinkSpeed;
- if (inf.ProcessCount > 0) olt.ProcessCount = inf.ProcessCount;
- if (inf.TcpConnections > 0) olt.TcpConnections = inf.TcpConnections;
- if (inf.TcpTimeWait > 0) olt.TcpTimeWait = inf.TcpTimeWait;
- if (inf.TcpCloseWait > 0) olt.TcpCloseWait = inf.TcpCloseWait;
- if (inf.Uptime > 0) olt.Uptime = inf.Uptime;
- if (inf.Delay > 0) olt.Delay = inf.Delay;
+ var online = this;
+
+ if (inf.AvailableMemory > 0) online.AvailableMemory = (Int32)(inf.AvailableMemory / 1024 / 1024);
+ if (inf.AvailableFreeSpace > 0) online.AvailableFreeSpace = (Int32)(inf.AvailableFreeSpace / 1024 / 1024);
+ if (inf.CpuRate > 0) online.CpuRate = inf.CpuRate;
+ if (inf.Temperature > 0) online.Temperature = inf.Temperature;
+ if (inf.Battery > 0) online.Battery = inf.Battery;
+ if (inf.UplinkSpeed > 0) online.UplinkSpeed = (Int64)inf.UplinkSpeed;
+ if (inf.DownlinkSpeed > 0) online.DownlinkSpeed = (Int64)inf.DownlinkSpeed;
+ if (inf.Uptime > 0) online.Uptime = inf.Uptime;
+ if (inf.Delay > 0) online.Delay = inf.Delay;
var dt = inf.Time.ToDateTime().ToLocalTime();
if (dt.Year > 2000)
{
- olt.LocalTime = dt;
- //olt.Offset = (Int32)Math.Round((dt - DateTime.Now).TotalSeconds);
- olt.Offset = (Int32)(inf.Time - DateTime.UtcNow.ToLong());
+ online.LocalTime = dt;
+ online.Offset = (Int32)(inf.Time - DateTime.UtcNow.ToLong());
}
- if (!inf.Processes.IsNullOrEmpty()) olt.Processes = inf.Processes;
- if (!inf.Macs.IsNullOrEmpty()) olt.MACs = inf.Macs;
- //if (!inf.COMs.IsNullOrEmpty()) olt.COMs = inf.COMs;
- if (!inf.IP.IsNullOrEmpty()) olt.IP = inf.IP;
+ if (!inf.IP.IsNullOrEmpty()) online.IP = inf.IP;
- //olt.Data = inf.ToJson();
var dic = inf.ToDictionary();
dic.Remove("Processes");
- olt.Data = dic.ToJson();
+ online.Data = dic.ToJson();
}
//private void CreateData(PingInfo inf, String ip)
diff --git a/Samples/ZeroServer/Program.cs b/Samples/ZeroServer/Program.cs
index 97f3fb3..59d97b4 100644
--- a/Samples/ZeroServer/Program.cs
+++ b/Samples/ZeroServer/Program.cs
@@ -67,7 +67,7 @@ app.MapControllerRoute(
app.RegisterService("ZeroServer", null, app.Environment.EnvironmentName);
// 反射查找并调用客户端测试,该代码仅用于测试,实际项目中不要这样做
-var clientType = "ZeroServer.Clients.ClientTest".GetTypeEx();
+var clientType = "ZeroClient.ClientTest".GetTypeEx();
var test = clientType?.GetMethodEx("Main").As<Func<IServiceProvider, Task>>();
if (test != null) _ = Task.Run(() => test(app.Services));
diff --git a/Samples/ZeroServer/Properties/launchSettings.json b/Samples/ZeroServer/Properties/launchSettings.json
index c4b50be..7efa44c 100644
--- a/Samples/ZeroServer/Properties/launchSettings.json
+++ b/Samples/ZeroServer/Properties/launchSettings.json
@@ -6,7 +6,7 @@
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
- "applicationUrl": "http://localhost:2880"
+ "applicationUrl": "http://localhost:6080"
}
}
}
\ No newline at end of file
diff --git a/Samples/ZeroServer/Services/IoTExtensions.cs b/Samples/ZeroServer/Services/IoTExtensions.cs
index 96f6885..92a8c16 100644
--- a/Samples/ZeroServer/Services/IoTExtensions.cs
+++ b/Samples/ZeroServer/Services/IoTExtensions.cs
@@ -1,8 +1,8 @@
-using NewLife.IoT.Models;
-using NewLife.Remoting.Extensions;
+using NewLife.Remoting.Extensions;
using NewLife.Remoting.Extensions.Models;
using NewLife.Remoting.Extensions.Services;
using NewLife.Remoting.Models;
+using ZeroServer.Models;
namespace ZeroServer.Services;
@@ -14,8 +14,6 @@ public static class IoTExtensions
ArgumentNullException.ThrowIfNull(setting);
// 逐个注册每一个用到的服务,必须做到清晰明了
- services.AddSingleton<QueueService>();
-
services.AddSingleton<IDeviceService, NodeService>();
services.AddTransient<ILoginRequest, LoginInfo>();
diff --git a/Samples/ZeroServer/Services/NodeOnlineService.cs b/Samples/ZeroServer/Services/NodeOnlineService.cs
index 3e1598c..4c5d320 100644
--- a/Samples/ZeroServer/Services/NodeOnlineService.cs
+++ b/Samples/ZeroServer/Services/NodeOnlineService.cs
@@ -80,7 +80,7 @@ public class NodeOnlineService : IHostedService
if (olt.CreateTime.Year > 2000 && olt.UpdateTime.Year > 2000)
{
node.OnlineTime += (Int32)(olt.UpdateTime - olt.CreateTime).TotalSeconds;
- node.Logout();
+ node.Update();
}
CheckOffline(node, "超时下线");
diff --git a/Samples/ZeroServer/Services/NodeService.cs b/Samples/ZeroServer/Services/NodeService.cs
index b5ab14a..3ad2ab4 100644
--- a/Samples/ZeroServer/Services/NodeService.cs
+++ b/Samples/ZeroServer/Services/NodeService.cs
@@ -2,7 +2,6 @@
using NewLife;
using NewLife.Caching;
using NewLife.Caching.Queues;
-using NewLife.IoT.Models;
using NewLife.Log;
using NewLife.Remoting;
using NewLife.Remoting.Extensions.Services;
@@ -11,6 +10,7 @@ using NewLife.Security;
using NewLife.Serialization;
using NewLife.Web;
using Zero.Data.Nodes;
+using ZeroServer.Models;
namespace ZeroServer.Services;
@@ -56,107 +56,72 @@ public class NodeService : IDeviceService
var code = inf.Code;
var secret = inf.Secret;
- var dv = Node.FindByCode(code);
+ var node = Node.FindByCode(code!, true);
+ if (node != null && !node.Enable) throw new ApiException(99, "禁止登录");
var autoReg = false;
- if (dv == null)
+ if (node == null)
{
- if (inf.ProductKey.IsNullOrEmpty()) throw new ApiException(ApiCode.NotFound, "找不到设备,且产品证书为空,无法登录");
-
- dv = AutoRegister(null, inf, ip);
+ node = AutoRegister(null, inf, ip);
autoReg = true;
}
else
{
- if (!dv.Enable) throw new ApiException(ApiCode.Forbidden, "禁止登录");
+ if (!node.Enable) throw new ApiException(ApiCode.Forbidden, "禁止登录");
// 校验唯一编码,防止客户端拷贝配置
var uuid = inf.UUID;
- if (!uuid.IsNullOrEmpty() && !dv.Uuid.IsNullOrEmpty() && uuid != dv.Uuid)
- WriteHistory(dv, source + "登录校验", false, $"新旧唯一标识不一致!(新){uuid}!={dv.Uuid}(旧)", ip);
+ if (!uuid.IsNullOrEmpty() && !node.Uuid.IsNullOrEmpty() && uuid != node.Uuid)
+ WriteHistory(node, source + "登录校验", false, $"新旧唯一标识不一致!(新){uuid}!={node.Uuid}(旧)", ip);
// 登录密码未设置或者未提交,则执行动态注册
- if (dv == null || !dv.Secret.IsNullOrEmpty()
- && (secret.IsNullOrEmpty() || !_passwordProvider.Verify(dv.Secret, secret)))
+ if (node == null || !node.Secret.IsNullOrEmpty()
+ && (secret.IsNullOrEmpty() || !_passwordProvider.Verify(node.Secret, secret)))
{
- if (inf.ProductKey.IsNullOrEmpty()) throw new ApiException(ApiCode.Unauthorized, "设备验证失败,且产品证书为空,无法登录");
-
- dv = AutoRegister(dv, inf, ip);
+ node = AutoRegister(node, inf, ip);
autoReg = true;
}
}
- //if (dv != null && !dv.Enable) throw new ApiException(99, "禁止登录");
-
- if (dv == null) throw new ApiException(ApiCode.Unauthorized, "节点鉴权失败");
+ if (node == null) throw new ApiException(ApiCode.Unauthorized, "节点鉴权失败");
- dv.Login(inf, ip);
+ node.Login(inf, ip);
// 在线记录
- var olt = GetOnline(dv, ip) ?? CreateOnline(dv, ip);
- olt.Save(inf, null, null);
-
- //SetChildOnline(dv, ip);
+ var olt = GetOnline(node, ip) ?? CreateOnline(node, ip);
+ olt.Save(inf, null, null, ip);
// 登录历史
- WriteHistory(dv, source + "设备鉴权", true, $"[{dv.Name}/{dv.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
{
- Name = dv.Name
+ Name = node.Name
};
// 动态注册,下发节点证书
- if (autoReg) rs.Secret = dv.Secret;
-
- return (dv, olt, rs);
- }
-
- /// <summary>设置设备在线,同时检查在线表</summary>
- /// <param name="dv"></param>
- /// <param name="ip"></param>
- /// <param name="reason"></param>
- public void SetDeviceOnline(Node dv, String ip, String reason)
- {
- // 如果已上线,则不需要埋点
- var tracer = _tracer;
- //if (dv.Online) tracer = null;
- using var span = tracer?.NewSpan(nameof(SetDeviceOnline), new { dv.Name, dv.Code, ip, reason });
+ if (autoReg) rs.Secret = node.Secret;
- var olt = GetOnline(dv, ip) ?? CreateOnline(dv, ip);
-
- dv.SetOnline(ip, reason);
-
- // 避免频繁更新心跳数
- if (olt.UpdateTime.AddSeconds(60) < DateTime.Now)
- olt.Save(null, null, null);
+ return (node, olt, rs);
}
/// <summary>自动注册</summary>
- /// <param name="device"></param>
+ /// <param name="node"></param>
/// <param name="inf"></param>
/// <param name="ip"></param>
/// <returns></returns>
/// <exception cref="ApiException"></exception>
- public Node AutoRegister(Node device, LoginInfo inf, String ip)
+ public Node AutoRegister(Node? node, LoginInfo inf, String ip)
{
// 全局开关,是否允许自动注册新产品
if (!_setting.AutoRegister) throw new ApiException(12, "禁止自动注册");
- // 验证产品,即使产品不给自动注册,也会插入一个禁用的设备
- var product = Product.FindByCode(inf.ProductKey);
- if (product == null || !product.Enable)
- throw new ApiException(13, $"无效产品[{inf.ProductKey}]!");
- //if (!product.Secret.IsNullOrEmpty() && !_passwordProvider.Verify(product.Secret, inf.ProductSecret))
- // throw new ApiException(13, $"非法产品[{product}]!");
-
- //// 检查白名单
- //if (!product.IsMatchWhiteIP(ip)) throw new ApiException(13, "非法来源,禁止注册");
-
var code = inf.Code;
+ if (code.IsNullOrEmpty()) code = inf.UUID.GetBytes().Crc().ToString("X8");
if (code.IsNullOrEmpty()) code = Rand.NextString(8);
- device ??= new Node
+ node ??= Node.FindByCode(code, false);
+ node ??= new Node
{
Code = code,
CreateIP = ip,
@@ -165,55 +130,50 @@ public class NodeService : IDeviceService
};
// 如果未打开动态注册,则把节点修改为禁用
- device.Enable = true;
-
- if (device.Name.IsNullOrEmpty()) device.Name = inf.Name;
+ node.Enable = true;
- device.ProductId = product.Id;
- //device.Secret = Rand.NextString(16);
- device.UpdateIP = ip;
- device.UpdateTime = DateTime.Now;
+ if (node.Name.IsNullOrEmpty()) node.Name = inf.Name;
- device.Save();
+ node.ProductCode = inf.ProductCode;
+ node.Secret = Rand.NextString(16);
+ node.UpdateIP = ip;
+ node.UpdateTime = DateTime.Now;
- // 更新产品设备总量避免界面无法及时获取设备数量信息
- device.Product.Fix();
+ node.Save();
- WriteHistory(device, "动态注册", true, inf.ToJson(false, false, false), ip);
+ WriteHistory(node, "动态注册", true, inf.ToJson(false, false, false), ip);
- return device;
+ return node;
}
/// <summary>注销</summary>
- /// <param name="device">设备</param>
+ /// <param name="model">设备</param>
/// <param name="reason">注销原因</param>
/// <param name="source">登录来源</param>
/// <param name="ip">远程IP</param>
/// <returns></returns>
- public IOnlineModel Logout(IDeviceModel device, String reason, String source, String ip)
+ public IOnlineModel Logout(IDeviceModel model, String reason, String source, String ip)
{
- var dv = device as Node;
- var olt = GetOnline(dv, ip);
- if (olt != null)
+ var node = model as Node;
+ var online = GetOnline(node, ip);
+ if (online != null)
{
- var msg = $"{reason} [{device}]]登录于{olt.CreateTime.ToFullString()},最后活跃于{olt.UpdateTime.ToFullString()}";
- WriteHistory(device, source + "设备下线", true, msg, ip);
- olt.Delete();
+ var msg = $"{reason} [{model}]]登录于{online.CreateTime.ToFullString()},最后活跃于{online.UpdateTime.ToFullString()}";
+ WriteHistory(model, source + "设备下线", true, msg, ip);
+ online.Delete();
- var sid = $"{dv.Id}@{ip}";
+ var sid = $"{node.Id}@{ip}";
_cache.Remove($"NodeOnline:{sid}");
// 计算在线时长
- if (olt.CreateTime.Year > 2000)
+ if (online.CreateTime.Year > 2000)
{
- dv.OnlineTime += (Int32)(DateTime.Now - olt.CreateTime).TotalSeconds;
- dv.Logout();
+ node.OnlineTime += (Int32)(DateTime.Now - online.CreateTime).TotalSeconds;
+ node.Update();
}
-
- //DeviceOnlineService.CheckOffline(device, "注销");
}
- return olt;
+ return online;
}
#endregion
@@ -223,63 +183,57 @@ public class NodeService : IDeviceService
/// <param name="token"></param>
/// <param name="ip"></param>
/// <returns></returns>
- public IOnlineModel Ping(IDeviceModel device, IPingRequest request, String token, String ip)
+ public IOnlineModel Ping(IDeviceModel model, IPingRequest request, String token, String ip)
{
- var dv = device as Node;
+ var node = model as Node;
var inf = request as PingInfo;
- if (inf != null && !inf.IP.IsNullOrEmpty()) dv.IP = inf.IP;
+ if (inf != null && !inf.IP.IsNullOrEmpty()) node.IP = inf.IP;
- // 自动上线
- if (dv != null && !dv.Online) dv.SetOnline(ip, "心跳");
+ node.UpdateIP = ip;
+ node.SaveAsync();
- dv.UpdateIP = ip;
- dv.SaveAsync();
+ var online = GetOnline(node, ip) ?? CreateOnline(node, ip);
+ online.Name = model.Name;
+ online.Save(null, inf, token, ip);
- var olt = GetOnline(dv, ip) ?? CreateOnline(dv, ip);
- olt.Name = device.Name;
- olt.GroupPath = dv.GroupPath;
- olt.ProductId = dv.ProductId;
- olt.Save(null, inf, token);
-
- return olt;
+ return online;
}
/// <summary></summary>
- /// <param name="device"></param>
+ /// <param name="node"></param>
/// <param name="ip"></param>
/// <returns></returns>
- protected virtual NodeOnline GetOnline(Node device, String ip)
+ public virtual NodeOnline GetOnline(Node node, String ip)
{
- var sid = $"{device.Id}@{ip}";
- var olt = _cache.Get<NodeOnline>($"NodeOnline:{sid}");
- if (olt != null)
+ var sid = $"{node.Id}@{ip}";
+ var online = _cache.Get<NodeOnline>($"NodeOnline:{sid}");
+ if (online != null)
{
_cache.SetExpire($"NodeOnline:{sid}", TimeSpan.FromSeconds(600));
- return olt;
+ return online;
}
- return NodeOnline.FindBySessionId(sid);
+ return NodeOnline.FindBySessionID(sid);
}
/// <summary>检查在线</summary>
- /// <param name="device"></param>
+ /// <param name="node"></param>
/// <param name="ip"></param>
/// <returns></returns>
- protected virtual NodeOnline CreateOnline(Node device, String ip)
+ public virtual NodeOnline CreateOnline(Node node, String ip)
{
- var sid = $"{device.Id}@{ip}";
- var olt = NodeOnline.GetOrAdd(sid);
- olt.ProductId = device.ProductId;
- olt.DeviceId = device.Id;
- olt.Name = device.Name;
- olt.IP = device.IP;
- olt.CreateIP = ip;
+ var sid = $"{node.Id}@{ip}";
+ var online = NodeOnline.GetOrAdd(sid);
+ online.NodeId = node.Id;
+ online.Name = node.Name;
+ online.IP = node.IP;
+ online.CreateIP = ip;
- olt.Creator = Environment.MachineName;
+ online.Creator = Environment.MachineName;
- _cache.Set($"NodeOnline:{sid}", olt, 600);
+ _cache.Set($"NodeOnline:{sid}", online, 600);
- return olt;
+ return online;
}
/// <summary>删除在线</summary>
@@ -337,33 +291,6 @@ public class NodeService : IDeviceService
}
/// <summary>
- /// 解码令牌,并验证有效性
- /// </summary>
- /// <param name="token"></param>
- /// <param name="tokenSecret"></param>
- /// <returns></returns>
- /// <exception cref="ApiException"></exception>
- public Node DecodeToken(String token, String tokenSecret)
- {
- //if (token.IsNullOrEmpty()) throw new ArgumentNullException(nameof(token));
- if (token.IsNullOrEmpty()) throw new ApiException(ApiCode.Unauthorized, "节点未登录");
-
- // 解码令牌
- var ss = tokenSecret.Split(':');
- var jwt = new JwtBuilder
- {
- Algorithm = ss[0],
- Secret = ss[1],
- };
-
- var rs = jwt.TryDecode(token, out var message);
- var node = Node.FindByCode(jwt.Subject);
- if (!rs) throw new ApiException(ApiCode.Forbidden, $"非法访问 {message}");
-
- return node;
- }
-
- /// <summary>
/// 验证并颁发令牌
/// </summary>
/// <param name="deviceCode"></param>
@@ -409,15 +336,14 @@ public class NodeService : IDeviceService
/// <summary>
/// 写设备历史
/// </summary>
- /// <param name="device"></param>
+ /// <param name="model"></param>
/// <param name="action"></param>
/// <param name="success"></param>
/// <param name="remark"></param>
/// <param name="ip"></param>
- public void WriteHistory(IDeviceModel device, String action, Boolean success, String remark, String ip)
+ public void WriteHistory(IDeviceModel model, String action, Boolean success, String remark, String ip)
{
- var traceId = DefaultSpan.Current?.TraceId;
- var hi = NodeHistory.Create(device as Node, action, success, remark, Environment.MachineName, ip, traceId);
+ NodeHistory.Create(model as Node, action, success, remark, Environment.MachineName, ip);
}
#endregion
}
\ No newline at end of file
diff --git a/Samples/ZeroServer/ZeroServer.csproj b/Samples/ZeroServer/ZeroServer.csproj
index e0e948f..52af78d 100644
--- a/Samples/ZeroServer/ZeroServer.csproj
+++ b/Samples/ZeroServer/ZeroServer.csproj
@@ -20,7 +20,6 @@
<ItemGroup>
<PackageReference Include="NewLife.Cube.Core" Version="6.1.2024.403" />
- <PackageReference Include="NewLife.IoT" Version="2.2.2024.501" />
<PackageReference Include="NewLife.Redis" Version="5.7.2024.602" />
<PackageReference Include="NewLife.Stardust.Extensions" Version="2.9.2024.402" />
</ItemGroup>