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

+0

新的工具包看起来不错,如果我的应用程序需要大部分功能,我会非常高兴地使用它。原来的一个对我非常有用,作为了解SDK的哪些部分是必要的,哪些可能会丢失。 –

+0

我的应用程序只需要一些函数(一旦会话打开):它每秒钟读取一个最多达40次的8个“Int16”整数数组,每秒钟检测一次“tick计数器”作为心跳次数,偶尔会写入'Boolean'启用远程过程调用。这使得90%的SDK是冗余的。我已经拼凑出一个*真正*简单的客户端,在约2000行代码中仅使用OPC UA Core。 –

+0

我对SDK和堆栈(与您的工具包相对)最大的挫折之一是它们似乎使用异常作为返回错误条件的机制。他们中很少有人似乎表明某些东西已经变得不可用,所以客户端代码变得混杂着“try ... catch”块,除了忽略这个异常之外,这些块基本上什么都不做。 –