OPC UA ServiceResultException(BadSecureChannelClosed)从服务器更新端点
我的C#应用程序使用OPC UA Core堆栈作为客户端与作为服务器运行的PLC连接。我没有使用OPC UA SDK,因为应用程序是WPF,而且SDK是不可理解的。OPC UA ServiceResultException(BadSecureChannelClosed)从服务器更新端点
我请教各种参考(包括OPC UA SDK和Converter Systems LLC WPF工具包),并拼凑起来我自己的方法来配置一个ITransportChannel
对象传递给Opc.UaSessionClient
构造。
我现在面临的问题是,为了获得一个端点描述和配置相匹配的服务器的预期值是,我用的是ConfiguredEndpoint.UpdateFromServer
,但这将引发ServiceResultException(BadSecureChannelClosed)
当其DiscoveryClient
对象被关闭。
我没有看到这个例外情况是由SDK包含的SimpleOpClient
项目报告的(它不是那么简单)。
任何想法这个功能可能是错误的?
private static ITransportChannel CreateTransportChannel(
ApplicationConfiguration appConfig,
String discoveryUrl)
{
// parse the selected URL.
Uri uri = new Uri(discoveryUrl);
EndpointDescription endpointDescription = new EndpointDescription
{
EndpointUrl = uri.ToString(),
SecurityMode = MessageSecurityMode.None,
SecurityPolicyUri = "http://opcfoundation.org/UA/SecurityPolicy#None"
};
// Configure the endpoint.
ServiceMessageContext messageContext = appConfig.CreateMessageContext();
EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(appConfig);
ConfiguredEndpoint endpoint = new ConfiguredEndpoint(null, endpointDescription, endpointConfiguration);
// The server may require that the endpoint configuration be adjusted
// to match its own settings.
if (endpoint.UpdateBeforeConnect)
{
// Update endpoint description using the discovery endpoint.
// EXCEPTION thrown during this call.
endpoint.UpdateFromServer(BindingFactory.Create(appConfig, messageContext));
endpointDescription = endpoint.Description;
endpointConfiguration = endpoint.Configuration;
}
// Sanity check for the presence of required security certificates.
X509Certificate2 clientCertificate = null;
if (endpointDescription.SecurityPolicyUri != SecurityPolicies.None)
{
if (appConfig.SecurityConfiguration.ApplicationCertificate == null)
{
Utils.Trace("ApplicationCertificate missing from Configuration.");
throw ServiceResultException.Create(StatusCodes.BadConfigurationError,
"ApplicationCertificate must be specified.");
}
clientCertificate = appConfig.SecurityConfiguration.ApplicationCertificate.Find(true);
if (clientCertificate == null)
{
Utils.Trace("ApplicationCertificate file could not be found.");
throw ServiceResultException.Create(StatusCodes.BadConfigurationError,
"ApplicationCertificate cannot be found.");
}
}
// Create a transport channel.
return SessionChannel.Create(
appConfig,
endpointDescription,
endpointConfiguration,
clientCertificate,
messageContext);
}
服务器返回BadSecureChannelClosed
结果吗?如果是这样,为什么?或者它是堆栈抛出的众多内部异常之一?
首先,你的代码工作正常。即使它抛出异常,它也会更新端点。每当库关闭套接字时,它都是opc.ua.core库的一个处理异常。如果在“例外设置”窗口中选择了“所有公共语言运行时例外情况不在此列表中”,则可以在调试器中看到它。其次,对于我们这些使用OPC Foundatation代码UA-.NET,如果参数为true,您将很高兴知道Session.Create()构造函数将自动更新端点。看到这个帖子的例子。 OPC UA : minimal code that browses the root node of a server
此外,既然您发现我的原始WPF工具包,我想邀请您参加我在GitHub上托管的新改进的WPF and UAP Toolkit。
新的工具包看起来不错,如果我的应用程序需要大部分功能,我会非常高兴地使用它。原来的一个对我非常有用,作为了解SDK的哪些部分是必要的,哪些可能会丢失。 –
我的应用程序只需要一些函数(一旦会话打开):它每秒钟读取一个最多达40次的8个“Int16”整数数组,每秒钟检测一次“tick计数器”作为心跳次数,偶尔会写入'Boolean'启用远程过程调用。这使得90%的SDK是冗余的。我已经拼凑出一个*真正*简单的客户端,在约2000行代码中仅使用OPC UA Core。 –
我对SDK和堆栈(与您的工具包相对)最大的挫折之一是它们似乎使用异常作为返回错误条件的机制。他们中很少有人似乎表明某些东西已经变得不可用,所以客户端代码变得混杂着“try ... catch”块,除了忽略这个异常之外,这些块基本上什么都不做。 –