OPCFoundation.NetStandard.Opc.Ua是OPC基金会发布的开源OPC UA包,提供Client读写库方便读写OPC 服务器数据。

     OPCFoundation.NetStandard.Opc.Ua开源项目地址:https://github.com/OPCFoundation/UA-.NETStandard

     使用时有几点需要注意。

1、订阅分组

        OPC UA的数据订阅分组,和OPC DA的有所不同,每个组数据项有限,这个值具体是多少与服务器的配置有关,一般几百到上千。每个组的订阅名称也不能相同,需要考虑订阅名称分类。服务器对与订阅资源是有限的,有的服务器必须显式的释放订阅资源,不然会造成订阅资源耗尽而订阅失败,必须重启服务端软件才能解决。 

2、连接断开

     OPC Client与服务器连接断开有两种情况:主动断开和被动断开

     客户端主动断开时,必须先注销订阅的数据分组项,再进行断开。目前这个库不能在连接关闭时自动释放所有服务器的连接资源,这个也是这个库不太友好的地方。      如果是服务端主动断开,很可能是服务器关闭了,这时直接关闭即可。

3、数据读取

      数据读取有订阅、同步和异步几种方法。订阅较为复杂但性能高、占用的网络带宽也最少。同步与异步仅调用语法有差异,其他类似。

      同步或异步都数据时,读多少数据点,就传入多少,然后到返回值中拿数据,C#可以作比较好的类型转换。

4、数据写入

      OPC UA在数据写入时,对数据类型有严格要求,数据类型不会自动转换,会写入失败。如果仅在C#系统内部写入数据,且仅少数点写入这时读有次数据,记录返回的数据类型,固定编码写入。

     在数据量较多,且有数据订阅的情况下,也可以记录每个点的数据类型,在写入数据时索引数据类型,然后自动转换。

    在把数据接口封装为API的情况下,同一个数据可以解析为很多数据类型,比如数据123,可以是Byte,I2、U2、I4、U4、R4等很多类型,反序列化时一般会解析为Single,直接调用写入会因数据类型不正确而失败。这时除了使用索引,自己处理数据兼容性问题,也可以多写几个wrapper来处理数据类型转换问题。

   示例的Controller类代码如下:

[ApiController]

[Route("[controller]/[action]")]

public class OpcUaControlServiceController : ControllerBase

{

private readonly ILogger _logger;

public OpcUaControlServiceController(ILogger logger)

{

_logger = logger;

}

///

/// 获取服务运行信息

///

/// 运行信息概览JSON

[HttpPost,HttpGet]

public string info()

{

return ApiContentResultMsg.Success(OpcUaControlService.Instance.Info());

}

///

/// 启动OpcUa 控制服务

///

/// 执行信息JSON

[HttpPost]

public string Start()

{

OpcUaControlService.Instance.Start();

return ApiContentResultMsg.Success();

}

///

/// 停止OpcUa 控制服务

///

/// 执行信息JSON

[HttpPost]

public string ShutDown()

{

OpcUaControlService.Instance.ShutDown();

return ApiContentResultMsg.Success();

}

///

/// 写入Int32 类型 OpcUa NodeId数据

///

/// 执行信息JSON

[HttpPost]

public string SyncWriteOpcUaInt32(String nodeId, Int32 value)

{

bool b = OpcUaControlService.Instance.SyncWriteOpcUaInt32(nodeId, value);

return b?ApiContentResultMsg.Success(): ApiContentResultMsg.Error("write fail!");

}

///

/// 写入float 类型 OpcUa NodeId数据

///

/// 执行信息JSON

[HttpPost]

public string SyncWriteOpcUaFloat(String nodeId, float value)

{

bool b = OpcUaControlService.Instance.SyncWriteOpcUaFloat(nodeId, value);

return b ? ApiContentResultMsg.Success() : ApiContentResultMsg.Error("write fail!");

}

///

/// 写入bool 类型 OpcUa NodeId数据

///

/// 执行信息JSON

[HttpPost]

public string SyncWriteOpcUaBool(String nodeId, bool value)

{

bool b = OpcUaControlService.Instance.SyncWriteOpcUaBool(nodeId, value);

return b ? ApiContentResultMsg.Success() : ApiContentResultMsg.Error("write fail!");

}

///

/// 写入String 类型 OpcUa NodeId数据

///

/// 执行信息JSON

[HttpPost]

public string SyncWriteOpcUaString(String nodeId, String value)

{

bool b = OpcUaControlService.Instance.SyncWriteOpcUaString(nodeId, value);

return b ? ApiContentResultMsg.Success() : ApiContentResultMsg.Error("write fail!");

}

}

5、参考资料

日本DeviceXPlorer OPC Server软件,在日系PLC和数控支持上比较友好,适用于1万点以内的采集服务,其自带了有个客户端的Demo,参考如下:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using Opc.Ua.Client;

using Opc.Ua.Configuration;

using Opc.Ua;

using System.Security.Cryptography.X509Certificates;

namespace DxpUaSimpleAPI

{

public class DxpUaSimpleClass

{

public struct ReadItemResults

{

public object m_readResultValue;

public StatusCode m_resultCodes;

public DateTime m_sourceTimeStamp;

public DateTime m_serverTimeStamp;

}

public struct WriteItemResults

{

public StatusCode m_resultCodes;

}

public delegate void onAsyncReadCompleteDelegate(List asyncReadNodeName, List AsyncReadItemResults);

public delegate void onAsyncWriteCompleteDelegate(List asyncWriteNodeName, List asyncResultStatus);

public delegate void monitoredItemNotification(List monitoredItems, List monitoredItemValue);

private Session m_clientSession = null;

private Dictionary m_subscriptionMap = new Dictionary();

private ApplicationInstance m_application = new ApplicationInstance();

private List m_subscriptions = new List();

public onAsyncReadCompleteDelegate m_ReadEventHandler = null;

public onAsyncWriteCompleteDelegate m_WriteEventHandler = null;

public monitoredItemNotification m_MonitoredEventHandler = null;

public struct CertificateStore

{

public string m_applicationCertificateFileName;

public string m_applicationCertificateStore;

public string m_trustedIssuerCertificatesStore;

public string m_TrustedPeerCertificatesStore;

public string m_RejectedCertificateStore;

}

public struct BrowseNodeResults

{

public QualifiedName m_browseName;

public ExpandedNodeId m_nodeIdList;

public LocalizedText m_displayName;

public StatusCode m_statusCodes;

}

public void Initialize()

{

m_application.ApplicationType = ApplicationType.Client;

m_application.ConfigSectionName = "Opc.Ua.SampleClient";

try

{

m_application.LoadApplicationConfiguration(false);

m_application.CheckApplicationInstanceCertificate(false, 0);

}

catch (Exception ex)

{

Console.WriteLine(" Initialize Exception" + ex.Message);

}

}

public bool Initialize(string sApplicationName, string sApplicationUri, string sProductUri, CertificateStore newCertificateStore, string sStoreType)

{

try

{

m_application.ApplicationConfiguration = new ApplicationConfiguration();

if (sApplicationName == "")

{

m_application.ApplicationConfiguration.ApplicationName = "OPC UA User Client";

}

if (sApplicationUri == "")

{

m_application.ApplicationConfiguration.ApplicationUri = "urn:localhost:TAKEBISHI:UserClient";

}

if (sProductUri == "")

{

m_application.ApplicationConfiguration.ProductUri = "http://opcfoundation.org/UA/SampleClient";

}

m_application.ApplicationConfiguration.ApplicationType = ApplicationType.Client;

m_application.ApplicationConfiguration.SecurityConfiguration.ApplicationCertificate = new CertificateIdentifier(new X509Certificate2(newCertificateStore.m_applicationCertificateFileName));

m_application.ApplicationConfiguration.SecurityConfiguration.ApplicationCertificate.StoreType = CertificateStoreType.Directory;

m_application.ApplicationConfiguration.SecurityConfiguration.ApplicationCertificate.StorePath = newCertificateStore.m_applicationCertificateStore;

m_application.ApplicationConfiguration.SecurityConfiguration.ApplicationCertificate.OpenStore();

m_application.ApplicationConfiguration.SecurityConfiguration.TrustedIssuerCertificates.StoreType = sStoreType;

m_application.ApplicationConfiguration.SecurityConfiguration.TrustedIssuerCertificates.StorePath = newCertificateStore.m_trustedIssuerCertificatesStore;

m_application.ApplicationConfiguration.SecurityConfiguration.TrustedIssuerCertificates.OpenStore();

m_application.ApplicationConfiguration.SecurityConfiguration.TrustedPeerCertificates.StoreType = sStoreType;

m_application.ApplicationConfiguration.SecurityConfiguration.TrustedPeerCertificates.StorePath = newCertificateStore.m_TrustedPeerCertificatesStore;

m_application.ApplicationConfiguration.SecurityConfiguration.TrustedPeerCertificates.OpenStore();

m_application.ApplicationConfiguration.SecurityConfiguration.RejectedCertificateStore = new CertificateStoreIdentifier();

m_application.ApplicationConfiguration.SecurityConfiguration.RejectedCertificateStore.StoreType = sStoreType;

m_application.ApplicationConfiguration.SecurityConfiguration.RejectedCertificateStore.StorePath = newCertificateStore.m_RejectedCertificateStore;

m_application.ApplicationConfiguration.SecurityConfiguration.RejectedCertificateStore.OpenStore();

m_application.ApplicationConfiguration.SecurityConfiguration.AutoAcceptUntrustedCertificates = false;

m_application.ApplicationConfiguration.CertificateValidator = new CertificateValidator();

StringCollection wellKnownDiscoveryUrls = new StringCollection();

wellKnownDiscoveryUrls.Add("http://{0}:52601/UADiscovery");

wellKnownDiscoveryUrls.Add("opc.tcp://{0}:4840");

wellKnownDiscoveryUrls.Add("http://{0}/UADiscovery/Default.svc");

m_application.ApplicationConfiguration.ClientConfiguration = new ClientConfiguration();

m_application.ApplicationConfiguration.ClientConfiguration.WellKnownDiscoveryUrls = wellKnownDiscoveryUrls;

m_application.CheckApplicationInstanceCertificate(false, 0);

}

catch (Exception ex)

{

Console.WriteLine(" Initialize Exception" + ex.Message);

return false;

}

return true;

}

public ConfiguredEndpoint GetEndPoint(string sUrl, MessageSecurityMode securityMode, string sSecurityPoricies)

{

try

{

ApplicationConfiguration configuration = m_application.ApplicationConfiguration;

EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(configuration);

EndpointDescription endpointDescription = null;

endpointDescription = new EndpointDescription();

endpointDescription.EndpointUrl = sUrl;

endpointDescription.SecurityLevel = 0;

endpointDescription.SecurityMode = securityMode;

endpointDescription.SecurityPolicyUri = sSecurityPoricies;

endpointDescription.Server.ApplicationName = endpointDescription.EndpointUrl;

endpointDescription.Server.ApplicationType = ApplicationType.Server;

endpointDescription.Server.ApplicationUri = endpointDescription.EndpointUrl;

ConfiguredEndpoint endpoint = new ConfiguredEndpoint(null, endpointDescription, endpointConfiguration);

return endpoint;

}

catch (Exception ex)

{

Console.WriteLine(" GetEndPoint Exception" + ex.Message);

return null;

}

}

public bool Connect(string sUrl, MessageSecurityMode securityMode, string sSecurityPoricies)

{

ApplicationConfiguration configuration = m_application.ApplicationConfiguration;

bool UpdateBeforeConnect = true;

string sSessionName = "session1";

uint nSessionTimeout = 3000;

UserIdentity userIdentity = null;

IList PreferredLocales = null;

ConfiguredEndpoint endpoint = GetEndPoint(sUrl, securityMode, sSecurityPoricies);

try

{

m_clientSession = Session.Create(configuration, endpoint, UpdateBeforeConnect, sSessionName, nSessionTimeout, userIdentity, PreferredLocales);

if (m_clientSession == null)

{

return false;

}

return true;

}

catch (Exception ex)

{

Console.WriteLine(" Session Create Exception" + ex.Message);

return false;

}

}

public bool DisConnect()

{

if (m_subscriptions.Count() > 0)

{

for (int i = 0; i < m_subscriptions.Count(); i++)

{

Subscription subscription = m_subscriptions[i];

if (m_subscriptionMap.ContainsKey(subscription.DisplayName))

{

subscription = m_subscriptionMap[subscription.DisplayName];

if (!RemoveAllMonitoredItems(subscription.DisplayName))

{

return false;

}

}

}

if (!m_clientSession.RemoveSubscriptions(m_subscriptions))

{

return false;

}

}

try

{

if (m_clientSession != null)

{

m_clientSession.Close();

m_clientSession.Dispose();

m_clientSession = null;

}

}

catch (Exception ex)

{

Console.WriteLine(" Session close Exception" + ex.Message);

return false;

}

return true;

}

public bool BrowseNode(NodeId targetNodeId, NodeId ReferenceType, out List results)

{

BrowseDescription nodeToBrowse = new BrowseDescription();

BrowseDescriptionCollection nodesToBrowse = new BrowseDescriptionCollection();

RequestHeader BrowseRequestHeader = new RequestHeader();

ViewDescription BrowseView = new ViewDescription();

BrowseResultCollection BrowseResults = new BrowseResultCollection();

uint requestMaxReferencesPerNode = 0;

DiagnosticInfoCollection BrowseDiagnosticsInfos = new DiagnosticInfoCollection();

nodeToBrowse.ReferenceTypeId = ReferenceType;

nodeToBrowse.NodeId = targetNodeId;

nodeToBrowse.IncludeSubtypes = true;

nodeToBrowse.NodeClassMask = (uint)(NodeClass.Object | NodeClass.Variable);

nodeToBrowse.ResultMask = (uint)BrowseResultMask.All;

nodeToBrowse.BrowseDirection = BrowseDirection.Forward;

nodesToBrowse.Add(nodeToBrowse);

results = new List();

BrowseNodeResults browseNodeResults = new BrowseNodeResults();

browseNodeResults.m_browseName = null;

browseNodeResults.m_nodeIdList = null;

browseNodeResults.m_displayName = null;

browseNodeResults.m_statusCodes = new StatusCode();

try

{

m_clientSession.Browse(BrowseRequestHeader, BrowseView, requestMaxReferencesPerNode, nodesToBrowse, out BrowseResults, out BrowseDiagnosticsInfos);

browseNodeResults.m_statusCodes = BrowseResults[0].StatusCode;

for (int i = 0; i < BrowseResults[0].References.Count(); i++)

{

browseNodeResults.m_browseName = BrowseResults[0].References[i].BrowseName;

browseNodeResults.m_nodeIdList = BrowseResults[0].References[i].NodeId;

browseNodeResults.m_displayName = BrowseResults[0].References[i].DisplayName;

results.Add(browseNodeResults);

}

}

catch (Exception ex)

{

Console.WriteLine(" BrowseNode Exception" + ex.Message);

return false;

}

return true;

}

public bool SyncRead(List readItemList, out List results)

{

RequestHeader ReadRequestHeader = new RequestHeader();

ReadRequestHeader.ReturnDiagnostics = 5000;

ReadValueIdCollection nodesToRead = new ReadValueIdCollection();

DataValueCollection ReadResults = new DataValueCollection();

DiagnosticInfoCollection ReadDiagnosticsInfos = null;

results = new List();

ReadItemResults readItemResults = new ReadItemResults();

readItemResults.m_readResultValue = 0;

readItemResults.m_resultCodes = new StatusCode();

readItemResults.m_serverTimeStamp = new DateTime();

readItemResults.m_sourceTimeStamp = new DateTime();

try

{

foreach (NodeId nodeId in readItemList)

{

ReadValueId readId = new ReadValueId();

readId.NodeId = nodeId;

readId.AttributeId = (uint)Attributes.Value;

nodesToRead.Add(readId);

}

m_clientSession.Read(ReadRequestHeader, 0, TimestampsToReturn.Both, nodesToRead, out ReadResults, out ReadDiagnosticsInfos);

for (int i = 0; i < ReadResults.Count(); i++)

{

readItemResults.m_resultCodes = ReadResults[i].StatusCode;

if (!StatusCode.IsBad(ReadResults[i].StatusCode))

{

readItemResults.m_readResultValue = ReadResults[i].Value;

readItemResults.m_sourceTimeStamp = ReadResults[i].SourceTimestamp;

readItemResults.m_serverTimeStamp = ReadResults[i].ServerTimestamp;

}

else

{

readItemResults.m_readResultValue = null;

readItemResults.m_sourceTimeStamp = DateTime.MinValue;

readItemResults.m_serverTimeStamp = DateTime.MinValue;

}

results.Add(readItemResults);

}

}

catch (Exception ex)

{

Console.WriteLine(" SyncRead Exception" + ex.Message);

return false;

}

return true;

}

public bool SyncWrite(List writeNodeIdList, List writeValueList, out List Results)

{

RequestHeader WriteRequestHeader = null;

Results = new List();

WriteItemResults writeItemResults = new WriteItemResults();

writeItemResults.m_resultCodes = new StatusCode();

WriteValueCollection writeValueCollection = new WriteValueCollection();

StatusCodeCollection WriteResults = null;

DiagnosticInfoCollection WriteDiagnosticsInfos = null;

try

{

for (int i = 0; i < writeNodeIdList.Count(); i++)

{

WriteValue valueToWrite = new WriteValue();

valueToWrite.NodeId = writeNodeIdList[i];

valueToWrite.AttributeId = (uint)Attributes.Value;

valueToWrite.Value.Value = writeValueList[i];

valueToWrite.Value.StatusCode = StatusCodes.Good;

valueToWrite.Value.ServerTimestamp = DateTime.MinValue;

writeValueCollection.Add(valueToWrite);

}

m_clientSession.Write(WriteRequestHeader, writeValueCollection, out WriteResults, out WriteDiagnosticsInfos);

if (WriteResults.Count() > 0)

{

for (int m = 0; m < WriteResults.Count(); m++)

{

writeItemResults.m_resultCodes = WriteResults[0];

Results.Add(writeItemResults);

}

}

else

{

return false;

}

}

catch (Exception ex)

{

Console.WriteLine(" SyncWrite Exception" + ex.Message);

return false;

}

return true;

}

public void ASyncRead(List readItemList)

{

ReadValueIdCollection nodesToRead = new ReadValueIdCollection();

try

{

foreach (NodeId nodeId in readItemList)

{

ReadValueId readId = new ReadValueId();

readId.NodeId = nodeId;

readId.AttributeId = (uint)Attributes.Value;

nodesToRead.Add(readId);

}

m_clientSession.BeginRead(null, 0, TimestampsToReturn.Both, nodesToRead, new AsyncCallback(AsyncReadCompleted), nodesToRead);

}

catch (Exception ex)

{

Console.WriteLine(" ASyncRead Exception" + ex.Message);

}

}

public void AsyncReadCompleted(IAsyncResult result)

{

try

{

if (!result.IsCompleted)

{

return;

}

EndRead(result);

}

catch (Exception ex)

{

Console.WriteLine(" ASyncRead Exception" + ex.Message);

}

}

public ResponseHeader EndRead(IAsyncResult result)

{

ReadResponse response = null;

DataValueCollection results = new DataValueCollection();

DiagnosticInfoCollection diagnosticInfos = new DiagnosticInfoCollection();

ReadValueIdCollection nodesToRead = (ReadValueIdCollection)result.AsyncState;

List readResults = new List();

IServiceResponse genericResponse = m_clientSession.TransportChannel.EndSendRequest(result);

if (genericResponse == null)

{

throw new ServiceResultException(StatusCodes.BadUnknownResponse);

}

ValidateResponse(genericResponse.ResponseHeader);

response = (ReadResponse)genericResponse;

results = response.Results;

diagnosticInfos = response.DiagnosticInfos;

ClientBase.ValidateResponse(results, nodesToRead);

ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead);

ReadItemResults readItemResults = new ReadItemResults();

readItemResults.m_readResultValue = 0;

readItemResults.m_resultCodes = new StatusCode();

readItemResults.m_serverTimeStamp = new DateTime();

readItemResults.m_sourceTimeStamp = new DateTime();

List asyncReadNodeName = new List();

for (int i = 0; i < results.Count; i++)

{

asyncReadNodeName.Add(nodesToRead[i].NodeId.ToString());

readItemResults.m_resultCodes = results[i].StatusCode;

if (!StatusCode.IsBad(results[i].StatusCode))

{

readItemResults.m_readResultValue = results[i].Value;

readItemResults.m_sourceTimeStamp = results[i].SourceTimestamp;

readItemResults.m_serverTimeStamp = results[i].ServerTimestamp;

}

else

{

readItemResults.m_readResultValue = null;

readItemResults.m_sourceTimeStamp = DateTime.MinValue;

readItemResults.m_serverTimeStamp = DateTime.MinValue;

}

readResults.Add(readItemResults);

}

m_ReadEventHandler(asyncReadNodeName, readResults);

return response.ResponseHeader;

}

public static void ValidateResponse(ResponseHeader header)

{

if (header == null)

{

throw new ServiceResultException(StatusCodes.BadUnknownResponse, "Deficiencies in the response.");

}

if (StatusCode.IsBad(header.ServiceResult))

{

throw new ServiceResultException(new ServiceResult(header.ServiceResult, header.ServiceDiagnostics, header.StringTable));

}

}

public void RegisterReadEventHandler(onAsyncReadCompleteDelegate eventHandler)

{

m_ReadEventHandler = eventHandler;

}

public void UnRegisterReadEventHandler(onAsyncReadCompleteDelegate eventHandler)

{

m_ReadEventHandler -= eventHandler;

}

public bool ASyncWrite(List writeNodeIdList, List writeValueList)

{

RequestHeader AsyncWriteRequestHeader = null;

WriteValueCollection nodesToAsyncWrite = new WriteValueCollection();

try

{

for (int i = 0; i < writeNodeIdList.Count(); i++)

{

WriteValue valueToAsyncWrite = new WriteValue();

valueToAsyncWrite.NodeId = writeNodeIdList[i];

TypeInfo typeInfo = TypeInfo.Construct(writeValueList[i]);

valueToAsyncWrite.Value.Value = writeValueList[i];

valueToAsyncWrite.AttributeId = (uint)Attributes.Value;

valueToAsyncWrite.Value.StatusCode = StatusCodes.Good;

valueToAsyncWrite.Value.ServerTimestamp = DateTime.MinValue;

valueToAsyncWrite.Value.SourceTimestamp = DateTime.MinValue;

nodesToAsyncWrite.Add(valueToAsyncWrite);

}

m_clientSession.BeginWrite(AsyncWriteRequestHeader, nodesToAsyncWrite, new AsyncCallback(AsyncWriteCompleted), nodesToAsyncWrite);

}

catch (Exception ex)

{

Console.WriteLine(" ASyncWrite Exception" + ex.Message);

return false;

}

return true;

}

public void AsyncWriteCompleted(IAsyncResult result)

{

try

{

if (!result.IsCompleted)

{

return;

}

EndWrite(result);

}

catch (Exception ex)

{

Console.WriteLine(" ASyncWrite Exception" + ex.Message);

}

}

public ResponseHeader EndWrite(IAsyncResult result)

{

WriteResponse response = null;

StatusCodeCollection results = new StatusCodeCollection();

DiagnosticInfoCollection diagnosticInfos = new DiagnosticInfoCollection();

WriteValueCollection nodesToWrite = (WriteValueCollection)result.AsyncState;

List writeResults = new List();

IServiceResponse genericResponse = m_clientSession.TransportChannel.EndSendRequest(result);

if (genericResponse == null)

{

throw new ServiceResultException(StatusCodes.BadUnknownResponse);

}

ValidateResponse(genericResponse.ResponseHeader);

response = (WriteResponse)genericResponse;

results = response.Results;

diagnosticInfos = response.DiagnosticInfos;

List asyncWriteNodeName = new List();

WriteItemResults writeItemResults = new WriteItemResults();

writeItemResults.m_resultCodes = new StatusCode();

for (int ii = 0; ii < results.Count; ii++)

{

asyncWriteNodeName.Add(nodesToWrite[ii].NodeId.ToString());

writeItemResults.m_resultCodes = results[ii];

writeResults.Add(writeItemResults);

}

m_WriteEventHandler(asyncWriteNodeName, writeResults);

return response.ResponseHeader;

}

public void RegisterWriteEventHandler(onAsyncWriteCompleteDelegate eventHandler)

{

m_WriteEventHandler = eventHandler;

}

public void UnRegisterWriteEventHandler(onAsyncReadCompleteDelegate eventHandler)

{

m_ReadEventHandler = null;

}

public bool CreateSubscription(string sSubscriptionName, int nPublishInterval)

{

Subscription subscription = new Subscription(m_clientSession.DefaultSubscription);

subscription.DisplayName = sSubscriptionName;

subscription.PublishingInterval = nPublishInterval;

subscription.LifetimeCount = 100;

subscription.KeepAliveCount = 10;

subscription.MaxNotificationsPerPublish = 1000;

subscription.Priority = 1;

subscription.PublishingEnabled = true;

subscription.TimestampsToReturn = TimestampsToReturn.Both;

if (m_clientSession.AddSubscription(subscription))

{

subscription.Create();

m_subscriptions.Add(subscription);

m_subscriptionMap.Add(sSubscriptionName, subscription);

return true;

}

else

{

return false;

}

}

public bool DestroySubscription(string sSubscriptionName)

{

Subscription subscription = null;

if (m_subscriptionMap.ContainsKey(sSubscriptionName))

{

subscription = m_subscriptionMap[sSubscriptionName];

if (RemoveAllMonitoredItems(sSubscriptionName))

{

if (m_clientSession.RemoveSubscription(subscription))

{

m_subscriptionMap.Remove(sSubscriptionName);

return true;

}

else

{

return false;

}

}

else

{

return false;

}

}

else

{

return false;

}

}

public bool AddMonitoredItem(string sSubscriptionName, List NodeIdList)

{

Subscription subscription = null;

if (m_subscriptionMap.ContainsKey(sSubscriptionName))

subscription = m_subscriptionMap[sSubscriptionName];

try

{

for (int count = 0; count < NodeIdList.Count(); count++)

{

MonitoredItem monitoredItem = new MonitoredItem(subscription.DefaultItem);

monitoredItem.StartNodeId = NodeIdList[count];

string monitoredItemName = "MonitoredItem_" + count.ToString();

monitoredItem.AttributeId = Attributes.Value;

monitoredItem.DisplayName = monitoredItemName;

monitoredItem.MonitoringMode = MonitoringMode.Reporting;

monitoredItem.SamplingInterval = subscription.PublishingInterval;

monitoredItem.QueueSize = 0;

monitoredItem.DiscardOldest = true;

if (Contains(subscription, monitoredItem))

{

Console.WriteLine("The item is already added.");

}

subscription.AddItem(monitoredItem);

monitoredItem.Handle = this;

subscription.ApplyChanges();

if (ServiceResult.IsBad(monitoredItem.Status.Error))

{

throw new ServiceResultException(monitoredItem.Status.Error);

}

monitoredItem.Notification += monitoredItem_Notification;

}

}

catch (Exception ex)

{

Console.WriteLine(" AddMonitoredItem Exception" + ex.Message);

return false;

}

return true;

}

public void RegisterMontioredItemEventHandler(monitoredItemNotification eventHandler)

{

m_MonitoredEventHandler = eventHandler;

}

public void UnRegisterMontioredItemEventHandler(monitoredItemNotification eventHandler)

{

m_MonitoredEventHandler = null;

}

public void monitoredItem_Notification(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)

{

List monitoredItems = new List();

List monitoredValues = new List();

MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification;

IList list = monitoredItem.DequeueValues();

DataValue data = list[0];

monitoredItems.Add(monitoredItem.DisplayName.ToString());

monitoredValues.Add(data.Value);

m_MonitoredEventHandler(monitoredItems, monitoredValues);

}

public bool RemoveMonitoredItems(string sSubscriptionName, List NodeIdList)

{

Subscription subscription = null;

if (m_subscriptionMap.ContainsKey(sSubscriptionName))

subscription = m_subscriptionMap[sSubscriptionName];

for (int count = 0; count < NodeIdList.Count(); count++)

{

foreach (MonitoredItem item in subscription.MonitoredItems)

{

if (NodeIdList[count] == item.StartNodeId)

{

Subscription removeSubscription = item.Subscription;

item.Subscription.RemoveItem(item);

removeSubscription.ApplyChanges();

}

}

}

return true;

}

public bool RemoveAllMonitoredItems(string sSubscriptionName)

{

Subscription subscription = null;

if (m_subscriptionMap.ContainsKey(sSubscriptionName))

subscription = m_subscriptionMap[sSubscriptionName];

foreach (MonitoredItem item in subscription.MonitoredItems)

{

MonitoredItem monitoredItem = item as MonitoredItem;

if (monitoredItem != null)

{

Subscription removeSubscription = monitoredItem.Subscription;

monitoredItem.Subscription.RemoveItem(monitoredItem);

removeSubscription.ApplyChanges();

}

}

return true;

}

public static bool Contains(Subscription subscription, MonitoredItem monitoredItem)

{

foreach (MonitoredItem item in subscription.MonitoredItems)

{

if (item.StartNodeId == monitoredItem.StartNodeId)

{

return true;

}

}

return false;

}

}

}

精彩文章

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。

发表评论

返回顶部暗黑模式