前言
OPC全称是OLE(Object Linking and Embedding) for Process Control。为了便于自动化行业不同厂家的设备和应用程序能相互交换数据,定义了一个统一的接口函数,就是OPC协议规范。OPC是基于WINDOWS COM/DOM的技术,可以使用统一的方式去访问不同设备厂商的产品数据。简单来说OPC就是为了用于设备和软件之间交换数据。
UA全称是unified architecture(统一架构)。为了应对标准化和跨平台的趋势,为了更好地推广OPC,OPC基金会近些年在之前OPC成功应用的基础上推出了一个新的OPC标准-OPC UA。OPC UA接口协议包含了之前的 A&E, DA,OPC XML DA or HDA,只使用一个地址空间就能访问之前所有的对象,而且不受WINDOWS平台限制,因为它是从传输层以上来定义的,导致了灵活性和安全性比之前的OPC都提升了。
OPC UA实质上是一种抽象的框架,是一个多层架构,其中的每一层完全是从其相邻层抽象而来。这些层定义了线路上的各种通信协议,以及能否安全地编码/解码包含有数据、数据类型定义等内容的讯息。利用这一核心服务和数据类型框架,人们可以在其基础上(继承)轻松添加更多功能。
OPC UA将成为一个转换工具。其它协议/标准(如BACnet)可以非常轻松地转换为OPC UA内的一个子集。
提示:以下是本篇文章正文内容,下面案例可供参考
一、OPCUA客户端初始化
在工程项目里引用OPCUA相关库,如下图所示:
OPCUA客户端初始化构建 ApplicationInstance和 ApplicationConfiguration,代码示例如下:
#region Private Fields
private ApplicationInstance application; //进程
private ApplicationConfiguration m_configuration; //配置信息
private Session m_session;
private bool m_IsConnected; //是否已经连接过
private int m_reconnectPeriod = 10; // 重连状态
private bool m_useSecurity;
private EndpointDescription endpointDescription;
private SessionReconnectHandler m_reconnectHandler;
private EventHandler m_ReconnectComplete;
private EventHandler m_ReconnectStarting;
private EventHandler m_KeepAliveComplete;
private EventHandler<string[]> m_ConnectComplete;
private EventHandler<OpcUaStatusEventArgs> m_OpcStatusChange;
private Dictionary<string, Subscription> dic_subscriptions; // 订阅的节点信息
#endregion
/// <summary>
/// 默认构造
/// </summary>
public OPCUAClient()
{
dic_subscriptions = new Dictionary<string, Subscription>();
var certificateValidator = new CertificateValidator();
certificateValidator.CertificateValidation += (sender, eventArgs) =>
{
if (ServiceResult.IsGood(eventArgs.Error))
eventArgs.Accept = true;
else if (eventArgs.Error.StatusCode.Code == StatusCodes.BadCertificateUntrusted)
eventArgs.Accept = true;
else
throw new Exception(string.Format("Failed", eventArgs.Error.Code, eventArgs.Error.AdditionalInfo));
};
SecurityConfiguration securityConfigurationcv = new SecurityConfiguration
{
AutoAcceptUntrustedCertificates = true,
RejectSHA1SignedCertificates = false,
MinimumCertificateKeySize = 1024,
};
certificateValidator.Update(securityConfigurationcv);
// Build the application configuration
application = new ApplicationInstance
{
ApplicationType = ApplicationType.Client,
ConfigSectionName = OpcUaName,
ApplicationConfiguration = new ApplicationConfiguration
{
ApplicationUri = "",
ApplicationName = OpcUaName,
ApplicationType = ApplicationType.Client,
CertificateValidator = certificateValidator,
ServerConfiguration = new ServerConfiguration
{
MaxSubscriptionCount = 10000,
MaxMessageQueueSize = 10000,
MaxNotificationQueueSize = 10000,
MaxPublishRequestCount = 10000
},
SecurityConfiguration = new SecurityConfiguration
{
AutoAcceptUntrustedCertificates = true,
},
TransportQuotas = new TransportQuotas
{
OperationTimeout = 600000,
MaxStringLength = 1048576,
MaxByteStringLength = 1048576,
MaxArrayLength = 65535,
MaxMessageSize = 4194304,
MaxBufferSize = 65535,
ChannelLifetime = 600000,
SecurityTokenLifetime = 3600000
},
ClientConfiguration = new ClientConfiguration
{
DefaultSessionTimeout = 60000,
MinSubscriptionLifetime = 10000
},
DisableHiResClock = true
}
};
m_configuration = application.ApplicationConfiguration;
}
二、与服务端建立连接
1、登录
OPCUA包含访客登录、用户名和密码登录以及安全证书登录三种方式。
代码如下(示例):
/// <summary>
/// 访客登录
/// </summary>
/// <returns></returns>
public bool GuestLogin()
{
try
{
UserIdentity uid = new UserIdentity(new AnonymousIdentityToken());
return true;
}
catch
{
return false;
}
}
/// <summary>
/// 用户密码登录
/// </summary>
/// <param name="UserName"></param>
/// <param name="PassWord"></param>
/// <returns></returns>
public bool UserIdentityLogin(string UserName,string PassWord)
{
try
{
UserIdentity uid = new UserIdentity(UserName, PassWord);
return true;
}
catch
{
return false;
}
}
/// <summary>
/// 证书登录
/// </summary>
/// <param name="CertificateFileName"></param>
/// <param name="PassWord"></param>
/// <returns></returns>
public bool CertificateLogin(string CertificateFileName,string PassWord)
{
try
{
X509Certificate2 certificate = new X509Certificate2(CertificateFileName, PassWord, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable);
UserIdentity uid = new UserIdentity(certificate);
return true;
}
catch
{
return false;
}
}
2、建立连接
与服务端连接时需要服务端指定的URL
代码如下(示例):
/// <summary>
/// 创建一个新session.
/// </summary>
/// <returns>URL</returns>
private async Task<Session> Connect(string serverUrl)
{
Disconnect();
if (m_configuration == null)
{
throw new ArgumentNullException("m_configuration");
}
// 通过连接地址选择 endpoint.
endpointDescription = CoreClientUtils.SelectEndpoint(serverUrl, UseSecurity);
EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(m_configuration);
ConfiguredEndpoint endpoint = new ConfiguredEndpoint(null, endpointDescription, endpointConfiguration);
m_session = await Session.Create(
m_configuration,
endpoint,
false,
false,
(string.IsNullOrEmpty(OpcUaName)) ? m_configuration.ApplicationName : OpcUaName,
60000,
UserIdentity,
new string[] { });
// 保持连接
m_session.KeepAlive += new KeepAliveEventHandler(Session_KeepAlive);
// 更新客户端状态
m_IsConnected = true;
// 触发连接完成事件
DoConnectComplete(null, new string[] { m_session.ConfiguredEndpoint.Description.Server.ApplicationName.ToString(),
m_session.ConfiguredEndpoint.Description.SecurityMode.ToString(),
m_session.ConfiguredEndpoint.Description.SecurityPolicyUri,m_session.ConfiguredEndpoint.Description.EndpointUrl});
// return the new session.
return m_session;
}