lixun 2 éve
szülő
commit
6cd222e93a

+ 36 - 2
src/YSAI.DAQ/YSAI.Core/interface/only/IOpc.cs

@@ -101,7 +101,24 @@ namespace YSAI.Core.@interface.only
         /// <summary>
         /// 请求
         /// </summary>
-        /// <param name="request">请求方法</param>
+        /// <param name="requestApi">
+        /// 请求方法
+        /// OPC服务名清单 = 0,
+        /// 连接OPC服务 = 1,
+        /// 浏览OPC服务下的所有标签列表 = 2,
+        /// 重连OPC服务 = 3,
+        /// 断开OPC服务的连接 = 4,
+        /// 删除OPC服务的连接(此服务已经建立的组和标签都会被删除) = 5,
+        /// 添加组 = 6,
+        /// 删除组(该组下已经添加的点位都会被删除) = 7,
+        /// 获取已添加的组名清单 = 9,
+        /// 批量在组下添加标签 = 10,
+        /// 获取组下已添加的点位清单 = 11,
+        /// 批量删除组下点位 = 12,
+        /// 批量读取组下点位值 = 13,
+        /// 获取与OPC的连接状态 = 14,
+        /// 写入点位值 = 15
+        /// </param>
         /// <param name="Param">参数</param>
         /// <returns>统一出参</returns>
         OperateResult Request(int requestApi, object? Param = null);
@@ -109,7 +126,24 @@ namespace YSAI.Core.@interface.only
         /// <summary>
         /// 请求
         /// </summary>
-        /// <param name="request">请求方法</param>
+        /// <param name="requestApi">
+        /// 请求方法
+        /// OPC服务名清单 = 0,
+        /// 连接OPC服务 = 1,
+        /// 浏览OPC服务下的所有标签列表 = 2,
+        /// 重连OPC服务 = 3,
+        /// 断开OPC服务的连接 = 4,
+        /// 删除OPC服务的连接(此服务已经建立的组和标签都会被删除) = 5,
+        /// 添加组 = 6,
+        /// 删除组(该组下已经添加的点位都会被删除) = 7,
+        /// 获取已添加的组名清单 = 9,
+        /// 批量在组下添加标签 = 10,
+        /// 获取组下已添加的点位清单 = 11,
+        /// 批量删除组下点位 = 12,
+        /// 批量读取组下点位值 = 13,
+        /// 获取与OPC的连接状态 = 14,
+        /// 写入点位值 = 15
+        /// </param>
         /// <param name="Param">参数</param>
         /// <returns>统一出参</returns>
         Task<OperateResult> RequestAsync(int requestApi, object? Param = null);

+ 14 - 20
src/YSAI.DAQ/YSAI.Core/reflection/ReflectionOperate.cs

@@ -130,15 +130,13 @@ namespace YSAI.Core.reflection
         /// key 标识符,$"{ClassData.SN}{MethodData.SN}"
         /// value (个个Dll反射的结果)
         /// </summary>
-        private ConcurrentDictionary<string, ReflectionMethodResult> MethodIocContainer;
+        private ConcurrentDictionary<string, ReflectionMethodResult> MethodIocContainer = new ConcurrentDictionary<string, ReflectionMethodResult>();
         /// <summary>
         /// 事件的IOC容器
         /// key 标识符,$"{ClassData.SN}{MethodData.SN}"
         /// value (个个Dll反射的结果)
         /// </summary>
-        private ConcurrentDictionary<string, ReflectionEventResult> EventIocContainer;
-
-       
+        private ConcurrentDictionary<string, ReflectionEventResult> EventIocContainer = new ConcurrentDictionary<string, ReflectionEventResult>();
 
 
         /// <summary>
@@ -150,14 +148,6 @@ namespace YSAI.Core.reflection
             Depart("Init");
             try
             {
-                if (MethodIocContainer == null)
-                {
-                    MethodIocContainer = new ConcurrentDictionary<string, ReflectionMethodResult>();
-                }
-                if (EventIocContainer == null)
-                {
-                    EventIocContainer = new ConcurrentDictionary<string, ReflectionEventResult>();
-                }
                 //得到DLL数据
                 foreach (var DllData in data.DllDatas)
                 {
@@ -258,10 +248,11 @@ namespace YSAI.Core.reflection
                 return Break("Init", false, ex.Message);
             }
         }
+
         /// <summary>
         /// 创建实例
         /// </summary>
-        /// <param name="type">类型</param>
+        /// <param name="NamespaceAndClassNameType">类型</param>
         /// <param name="ConstructorParam">构造函数入参</param>
         /// <returns></returns>
         private object? CreateInstance(Type? NamespaceAndClassNameType, object[]? ConstructorParam)
@@ -349,11 +340,11 @@ namespace YSAI.Core.reflection
             }
             return null;
         }
+
         /// <summary>
         /// 执行方法
         /// </summary>
-        /// <param name="ClassSn">实例的唯一标识符</param>
-        /// <param name="MethodSn">方法的唯一标识符</param>
+        /// <param name="SN">方法的唯一标识符</param>
         /// <param name="MethodParam">方法参数</param>
         /// <returns></returns>
         public object? ExecuteMethod(string? SN, object[]? MethodParam = null)
@@ -371,7 +362,7 @@ namespace YSAI.Core.reflection
             }
             else
             {
-                return "执行失败,未找到反射的数据";
+                return Break(Depart("ExecuteMethod"),false, "执行失败,未找到反射的数据");
             }
         }
 
@@ -414,7 +405,7 @@ namespace YSAI.Core.reflection
         /// <param name="P5">五个参数的事件动作</param>
         /// <param name="P6">六个参数的事件动作</param>
         /// <returns></returns>
-        public (bool state, string message) RegisterEvent(string SN, bool Register,
+        public OperateResult RegisterEvent(string SN, bool Register,
             Action<object>? P1 = null,
             Action<object, object>? P2 = null,
             Action<object, object, object>? P3 = null,
@@ -422,6 +413,7 @@ namespace YSAI.Core.reflection
             Action<object, object, object, object, object>? P5 = null,
             Action<object, object, object, object, object, object>? P6 = null)
         {
+            Depart("RegisterEvent");
             ReflectionEventResult? reflectionEventResult = GetEvent(SN);
             if (reflectionEventResult != null)
             {
@@ -460,16 +452,16 @@ namespace YSAI.Core.reflection
                     {
                         reflectionEventResult.Event.RemoveEventHandler(reflectionEventResult.InstanceObject, @delegate);
                     }
-                    return (true, "事件注册成功");
+                    return Break("RegisterEvent", true, "事件注册成功");
                 }
                 else
                 {
-                    return (false, "事件注册失败,未找到反射的数据类型");
+                    return Break("RegisterEvent", false, "事件注册失败,未找到反射的数据类型");
                 }
             }
             else
             {
-                return (false, "事件注册失败,未找到反射的数据");
+                return Break("RegisterEvent", false, "事件注册失败,未找到反射的数据");
             }
         }
 
@@ -501,6 +493,8 @@ namespace YSAI.Core.reflection
 
         public void Dispose()
         {
+            MethodIocContainer.Clear();
+            EventIocContainer.Clear();
             GC.Collect();
         }
     }

+ 0 - 3
src/YSAI.DAQ/YSAI.Core/subscribe/SubscribeOperate.cs

@@ -141,7 +141,6 @@ namespace YSAI.Core.subscription
             }
             return true;
         }
-
         /// <summary>
         /// 执行轮询
         /// </summary>
@@ -240,8 +239,6 @@ namespace YSAI.Core.subscription
                 Thread.Sleep(basics.SleepTime);
             }
         }
-
-
         /// <summary>
         /// 释放
         /// </summary>

+ 18 - 18
src/YSAI.DAQ/YSAI.Opc/da/http/OpcDaHttpOperate.cs

@@ -178,57 +178,57 @@ namespace YSAI.Opc.da.http
                 //判断状态是否正常
                 if (code.Equals("1"))
                 {
-                    object jsonobj = null;
+                    object? jsonObj = null;
                     switch (request)
                     {
                         case OpcDaHttpData.RequestMethod.ReqOPCServerNameList:
-                            jsonobj = JsonTool.StringToJsonEntity<ReqOPCServerNameList.Response>(ResponseData.ResponseData);  //json 数据转 结构体
+                            jsonObj = JsonTool.StringToJsonEntity<ReqOPCServerNameList.Response>(ResponseData.ResponseData);  //json 数据转 结构体
                             break;
                         case OpcDaHttpData.RequestMethod.ReqConnectToOPC:
-                            jsonobj = JsonTool.StringToJsonEntity<ReqConnectToOPC.Response>(ResponseData.ResponseData);
+                            jsonObj = JsonTool.StringToJsonEntity<ReqConnectToOPC.Response>(ResponseData.ResponseData);
                             break;
                         case OpcDaHttpData.RequestMethod.ReqGetALLItemsOfOPC:
-                            jsonobj = JsonTool.StringToJsonEntity<ReqGetALLItemsOfOPC.Response>(ResponseData.ResponseData);
+                            jsonObj = JsonTool.StringToJsonEntity<ReqGetALLItemsOfOPC.Response>(ResponseData.ResponseData);
                             break;
                         case OpcDaHttpData.RequestMethod.ReqReConnectOfOPC:
-                            jsonobj = JsonTool.StringToJsonEntity<ReqReConnectOfOPC.Response>(ResponseData.ResponseData);
+                            jsonObj = JsonTool.StringToJsonEntity<ReqReConnectOfOPC.Response>(ResponseData.ResponseData);
                             break;
                         case OpcDaHttpData.RequestMethod.ReqDisConnectOfOPC:
-                            jsonobj = JsonTool.StringToJsonEntity<ReqDisConnectOfOPC.Response>(ResponseData.ResponseData);
+                            jsonObj = JsonTool.StringToJsonEntity<ReqDisConnectOfOPC.Response>(ResponseData.ResponseData);
                             break;
                         case OpcDaHttpData.RequestMethod.ReqDeleteConnectOfOPC:
-                            jsonobj = JsonTool.StringToJsonEntity<ReqDeleteConnectOfOPC.Response>(ResponseData.ResponseData);
+                            jsonObj = JsonTool.StringToJsonEntity<ReqDeleteConnectOfOPC.Response>(ResponseData.ResponseData);
                             break;
                         case OpcDaHttpData.RequestMethod.ReqAddGroupOfOPC:
-                            jsonobj = JsonTool.StringToJsonEntity<ReqAddGroupOfOPC.Response>(ResponseData.ResponseData);
+                            jsonObj = JsonTool.StringToJsonEntity<ReqAddGroupOfOPC.Response>(ResponseData.ResponseData);
                             break;
                         case OpcDaHttpData.RequestMethod.ReqDelGroupOfOPC:
-                            jsonobj = JsonTool.StringToJsonEntity<ReqDelGroupOfOPC.Response>(ResponseData.ResponseData);
+                            jsonObj = JsonTool.StringToJsonEntity<ReqDelGroupOfOPC.Response>(ResponseData.ResponseData);
                             break;
                         case OpcDaHttpData.RequestMethod.ReqGetGroupsOfOPC:
-                            jsonobj = JsonTool.StringToJsonEntity<ReqGetGroupsOfOPC.Response>(ResponseData.ResponseData);
+                            jsonObj = JsonTool.StringToJsonEntity<ReqGetGroupsOfOPC.Response>(ResponseData.ResponseData);
                             break;
                         case OpcDaHttpData.RequestMethod.ReqAddItemsOfGroup:
-                            jsonobj = JsonTool.StringToJsonEntity<ReqAddItemsOfGroup.Response>(ResponseData.ResponseData);
+                            jsonObj = JsonTool.StringToJsonEntity<ReqAddItemsOfGroup.Response>(ResponseData.ResponseData);
                             break;
                         case OpcDaHttpData.RequestMethod.ReqGetItemsOfGroup:
-                            jsonobj = JsonTool.StringToJsonEntity<ReqGetItemsOfGroup.Response>(ResponseData.ResponseData);
+                            jsonObj = JsonTool.StringToJsonEntity<ReqGetItemsOfGroup.Response>(ResponseData.ResponseData);
                             break;
                         case OpcDaHttpData.RequestMethod.ReqDelItemsOfGroup:
-                            jsonobj = JsonTool.StringToJsonEntity<ReqDelItemsOfGroup.Response>(ResponseData.ResponseData);
+                            jsonObj = JsonTool.StringToJsonEntity<ReqDelItemsOfGroup.Response>(ResponseData.ResponseData);
                             break;
                         case OpcDaHttpData.RequestMethod.ReqReadItemsValueOfGroup:
-                            jsonobj = JsonTool.StringToJsonEntity<ReqReadItemsValueOfGroup.Response>(ResponseData.ResponseData);
+                            jsonObj = JsonTool.StringToJsonEntity<ReqReadItemsValueOfGroup.Response>(ResponseData.ResponseData);
                             break;
                         case OpcDaHttpData.RequestMethod.ReqGetConnectStatusOfOPC:
-                            jsonobj = JsonTool.StringToJsonEntity<ReqGetConnectStatusOfOPC.Response>(ResponseData.ResponseData);
+                            jsonObj = JsonTool.StringToJsonEntity<ReqGetConnectStatusOfOPC.Response>(ResponseData.ResponseData);
                             break;
                         case OpcDaHttpData.RequestMethod.ReqWriteItemValue:
-                            jsonobj = JsonTool.StringToJsonEntity<ReqWriteItemValue.Response>(ResponseData.ResponseData);
+                            jsonObj = JsonTool.StringToJsonEntity<ReqWriteItemValue.Response>(ResponseData.ResponseData);
                             break;
                     }
-                    OnEventHandler?.Invoke(this, new OpcDaHttpData.EventParam() { Json = jsonobj, Message = "请求成功", RequestMethod = request, State = true });  //事件抛出
-                    return Break("Request", true, RData: jsonobj, RType: Core.@enum.ResultType.Json);  //返回数据
+                    OnEventHandler?.Invoke(this, new OpcDaHttpData.EventParam() { Json = jsonObj, Message = "请求成功", RequestMethod = request, State = true });  //事件抛出
+                    return Break("Request", true, RData: jsonObj, RType: Core.@enum.ResultType.Json);  //返回数据
                 }
                 else
                 {

+ 4 - 3
src/YSAI.DAQ/YSAI.Opc/ua/client/OpcUaClientData.cs

@@ -68,12 +68,13 @@ namespace YSAI.Opc.ua.client
             /// 取样时间间隔
             /// </summary>
             [Description("取样时间间隔")]
-            public int SamplingInterval { get; set; }
+            public int SamplingInterval { get; set; } = 1000;
 
             /// <summary>
-            /// 分配给订阅的优先级
+            /// 发布时间间隔
             /// </summary>
-            public byte Priority { get; set; } = 100;
+            [Description("发布时间间隔")]
+            public byte PublishingInterval { get; set; } = 1000;
 
             /// <summary>
             /// 重写基类中的Equals方法

+ 25 - 18
src/YSAI.DAQ/YSAI.Opc/ua/client/OpcUaClientOperate.cs

@@ -768,14 +768,17 @@ namespace YSAI.Opc.ua.client
                             {
                                 if (!item.IsEnable) continue;
 
-                                MonitoredItem intMonitoredItem = new MonitoredItem(allSubscriptions[Tag].DefaultItem);
-                                intMonitoredItem.StartNodeId = new NodeId(item.AddressName);  //标识要监视的节点的浏览路径的开始节点
-                                intMonitoredItem.AttributeId = Attributes.Value;  //要监视的属性
-                                intMonitoredItem.DisplayName = item.AddressName;  //被监控项的显示名称
-                                intMonitoredItem.SamplingInterval = basics.SamplingInterval;  //采样间隔
-                                intMonitoredItem.Notification += async delegate (MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e) { OnMonitoredItemNotification(monitoredItem, e, item); };  //重写事件添加一个参数
-
-                                allSubscriptions[Tag].AddItem(intMonitoredItem);  //添加订阅
+                                MonitoredItem monitoredItem = new MonitoredItem(allSubscriptions[Tag].DefaultItem);
+                                monitoredItem.StartNodeId = new NodeId(item.AddressName);  //标识要监视的节点的浏览路径的开始节点
+                                monitoredItem.AttributeId = Attributes.Value;  //要监视的属性
+                                monitoredItem.DisplayName = item.AddressName;  //被监控项的显示名称
+                                monitoredItem.SamplingInterval = basics.SamplingInterval;  //采样间隔
+                                monitoredItem.MonitoringMode = MonitoringMode.Reporting;  //采集模式
+                                monitoredItem.QueueSize = uint.MaxValue;  //队列大小
+                                monitoredItem.DiscardOldest = true;  //当队列满了是否丢弃早期数据
+                                monitoredItem.Handle = this;  //本地监听地址
+                                allSubscriptions[Tag].AddItem(monitoredItem);  //添加订阅
+                                monitoredItem.Notification += delegate (MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e) { OnMonitoredItemNotification(monitoredItem, e, item); };  //重写事件添加一个参数
                             }
 
                             if (Nodes.Count > 0)
@@ -798,25 +801,29 @@ namespace YSAI.Opc.ua.client
                             //订阅
                             Subscription subscription = new Subscription(clientSession?.DefaultSubscription);
                             subscription.PublishingEnabled = true;//是否启用发布
-                            subscription.PublishingInterval = 0; //出版间隔
+                            subscription.PublishingInterval = basics.PublishingInterval; //出版间隔
                             subscription.KeepAliveCount = uint.MaxValue;  //存活数量
                             subscription.LifetimeCount = uint.MaxValue;  //生命周期
                             subscription.MaxNotificationsPerPublish = uint.MaxValue;  //每个发布请求的最大通知数
-                            subscription.Priority = basics.Priority;  //分配给订阅的优先级
+                            subscription.Priority = 1;  //分配给订阅的优先级
                             subscription.DisplayName = Tag;  //订阅的显示名称
-
+                            subscription.TimestampsToReturn = TimestampsToReturn.Both;  //与通知消息一起返回的时间戳
                             //循环添加
                             foreach (var item in Nodes)
                             {
                                 if (!item.IsEnable) continue;
 
-                                MonitoredItem intMonitoredItem = new MonitoredItem(subscription.DefaultItem);
-                                intMonitoredItem.StartNodeId = new NodeId(item.AddressName);  //标识要监视的节点的浏览路径的开始节点
-                                intMonitoredItem.AttributeId = Attributes.Value;  //要监视的属性
-                                intMonitoredItem.DisplayName = item.AddressName;  //被监控项的显示名称
-                                intMonitoredItem.SamplingInterval = basics.SamplingInterval;  //采样间隔
-                                intMonitoredItem.Notification += async delegate (MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e) { OnMonitoredItemNotification(monitoredItem, e, item); };  //重写事件添加一个参数
-                                subscription.AddItem(intMonitoredItem);   //添加订阅通知项
+                                MonitoredItem monitoredItem = new MonitoredItem(subscription.DefaultItem);
+                                monitoredItem.StartNodeId = new NodeId(item.AddressName);  //标识要监视的节点的浏览路径的开始节点
+                                monitoredItem.AttributeId = Attributes.Value;  //要监视的属性
+                                monitoredItem.DisplayName = item.AddressName;  //被监控项的显示名称
+                                monitoredItem.SamplingInterval = basics.SamplingInterval;  //采样间隔
+                                monitoredItem.MonitoringMode = MonitoringMode.Reporting;  //采集模式
+                                monitoredItem.QueueSize = uint.MaxValue;  //队列大小
+                                monitoredItem.DiscardOldest = true;  //当队列满了是否丢弃早期数据
+                                monitoredItem.Handle = this;  //本地监听地址
+                                subscription.AddItem(monitoredItem);   //添加订阅通知项
+                                monitoredItem.Notification += delegate (MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e) { OnMonitoredItemNotification(monitoredItem, e, item); };  //重写事件添加一个参数
                             }
                             //不在主线程中实现
                             Task.Run(async () =>

+ 1 - 1
src/YSAI.DAQ/YSAI.Test/YSAI.Test.csproj

@@ -11,7 +11,7 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.3" />
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.0" />
     <PackageReference Include="MSTest.TestAdapter" Version="3.1.1" />
     <PackageReference Include="MSTest.TestFramework" Version="3.1.1" />
     <PackageReference Include="coverlet.collector" Version="6.0.0">