西门子OPC UA和.NET C#客户端无法连接服务器?

3
我尝试使用此页面提供的客户端连接OPC UA服务器:https://support.industry.siemens.com/cs/document/42014088/programming-an-opc-ua-net-client-with-c%23-for-the-simatic-net-opc-ua-server?dti=0&lc=en-US。使用Siemens OPC Scount v10连接到OPC UA服务器正常工作。当使用文章中提供的客户端连接到OPC UA服务器时,我收到以下消息:

无法打开UA TCP请求通道。

异常的堆栈跟踪如下:

    Server stack trace: 
   at Opc.Ua.Bindings.UaTcpRequestChannel.OnEndOpen(IAsyncResult result)
   at Opc.Ua.Bindings.UaTcpRequestChannel.OnOpen(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.CallOpenOnce.System.ServiceModel.Channels.ServiceChannel.ICallOnce.Call(ServiceChannel channel, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan timeout, CallOnceManager cascade)
   at System.ServiceModel.Channels.ServiceChannel.EnsureOpened(TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs)
   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]: 
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   at Opc.Ua.ISessionChannel.CreateSession(CreateSessionMessage request)
   at Opc.Ua.SessionChannel.CreateSession(CreateSessionMessage request)
   at Opc.Ua.SessionClient.CreateSession(RequestHeader requestHeader, ApplicationDescription clientDescription, String serverUri, String endpointUrl, String sessionName, Byte[] clientNonce, Byte[] clientCertificate, Double requestedSessionTimeout, UInt32 maxResponseMessageSize, NodeId& sessionId, NodeId& authenticationToken, Double& revisedSessionTimeout, Byte[]& serverNonce, Byte[]& serverCertificate, EndpointDescriptionCollection& serverEndpoints, SignedSoftwareCertificateCollection& serverSoftwareCertificates, SignatureData& serverSignature, UInt32& maxRequestMessageSize)
   at Opc.Ua.Client.Session.Open(String sessionName, UInt32 sessionTimeout, IUserIdentity identity, IList`1 preferredLocales)
   at Opc.Ua.Client.Session.Open(String sessionName, IUserIdentity identity)

任何帮助都将不胜感激。OPC UA服务器运行在西门子Simatic HMI TP700 Comfort上。OPC UA服务器上的配置默认设置。
在andrewcullen的提示后,我们在tracelog.txt文件中得到了下面的日志和错误信息,在捕获异常时显示:
“连接服务器时发生意外错误。”
    PID:4196 ************************* Logging started at 02/03/2016 07:41:34 *************************
4196 - 07:41:38.742 GetEndpoints Called. RequestHandle=1, PendingRequestCount=1
4196 - 07:41:38.992 SECURE CHANNEL CREATED [TcpClientChannel UA-TCP 1.00.238.1] [ID=12752] Connected To: opc.tcp://xxx.xxx.xxx.xxx:4870/
4196 - 07:41:39.008 TCPCLIENTCHANNEL SOCKET CONNECTED: 00000698, ChannelId=12752
4196 - 07:41:39.008 SECURE CHANNEL CREATED [Opc.Ua.ChannelBase WCF Client 1.00.238.1] [ID=] Connected To: opc.tcp://xxx.xxx.xxx.xxx:4870/
4196 - 07:41:39.101 GetEndpoints Completed. RequestHandle=1, PendingRequestCount=0
4196 - 07:41:39.132 TCPCLIENTCHANNEL SOCKET CLOSED: 00000698, ChannelId=12752
4196 - 07:41:44.230 Writing rejected certificate to directory: 
4196 - 07:41:59.694 CreateSession Called. RequestHandle=1, PendingRequestCount=1
4196 - 07:42:13.672 TCPCLIENTCHANNEL SOCKET CLOSED: 000007C0, ChannelId=0
4196 - 07:42:13.750 CreateSession Completed. RequestHandle=1, PendingRequestCount=0

我从西门子官方支持部门得到了答案:

此应用程序尚未与Comfort Panel一起测试。 例如,代码包含块读取和块写入,在面板服务器上不受支持。 因此,此应用程序将无法正常工作。

2个回答

2
这个西门子UaClient使用了一个名为“ClientAPI”的库,它扩展了OPC Foundation的Opc.Ua.Core和Opc.Ua.Client。 ClientAPI有许多不错的Helper函数,可以简化连接和订阅过程。但是,在Connect(string Url)的代码中,我看到它正在使用原始的WCF-style通道。而您的堆栈跟踪显示WCF类型正在抛出难以诊断的异常。 我会更改两件事情:

首先,配置跟踪以将其写入文件。在ClientAPI中,找到Helpers.CreateClientConfiguration()并添加

// add trace config before calling validate
configuration.TraceConfiguration = new TraceConfiguration {
OutputFilePath="tracelog.txt", 
DeleteOnLoad = true, 
TraceMasks = Utils.TraceMasks.All };
configuration.Validate(ApplicationType.Client);    

其次,升级连接所使用的通道类型。在ClientAPI中,找到Server.Connect(string url),并按如下修改中间部分:

// Initialize the channel which will be created with the server.
// SessionChannel channel = SessionChannel.Create(
//    configuration,
//    endpointDescription,
//    endpointConfiguration,
//    bindingFactory,
//    clientCertificate,
//    null);
ITransportChannel channel = WcfChannelBase.CreateUaBinaryChannel(
    configuration,
    endpointDescription,
   endpointConfiguration,
   clientCertificate,
   configuration.CreateMessageContext());

// Wrap the channel with the session object.
// This call will fail if the server does not trust the client certificate.
// m_Session = new Session(channel, configuration, endpoint);
 m_Session = new Session(channel, configuration, endpoint, clientCertificate);

编辑2/4:

从跟踪日志中,您可能会发现证书错误。在创建新会话时,客户端和服务器都提供并验证对方的证书。默认情况下,UaClient从Windows存储LocalMachine\My(也称为个人)检索其证书。API在第一次运行时生成此证书(需要以管理员身份运行第一次)(要查看此证书,请运行'certlm.msc')。

在服务器机器上,服务器将通过检查是否与其“TrustedPeerList”中的证书匹配来验证客户端的证书。服务器通常使用目录存储受信任的证书。如果客户端证书不受信任,则服务器将将客户端证书复制到“RejectedCertificates”目录中。您需要将在'RejectedCertificates'中找到的证书复制到受信任的证书目录中。

回到客户端机器上,客户端将验证服务器的证书。此客户端使用Windows存储进行验证'LocalMachine\My'(也称为个人)。客户端注册一个事件处理程序而不是使用'Rejected'目录,该事件处理程序打开一个消息框,询问您是否希望接受服务器的证书。如果您选择接受,则客户端设置eventArg e.Accept = true; 为了抑制消息框,应使用工具'certlm.msc'将服务器的证书导入客户端的'LocalMachine\My'(也称为个人)。


我们测试了您的建议。我已将结果添加到上面的原始帖子中。根据我们对tracelog.txt内容的理解,HMI上的OPC UA正在拒绝客户端证书? - Gašper Sladič
我有同样的问题。西门子正在调查此事。我建议在他们的网站上开始一个服务请求,并将所有数据添加到其中。 - user1419979

0
尝试使用DNS名称对服务器进行ping测试。如果服务器无法访问,则必须编辑C:\ Windows \ System32 \ drivers \ etc ...中的Hosts文件。以管理员身份打开记事本,然后打开Hosts文件,并输入IP地址到主机名的映射,如下所示:

xxx.xxx.xxx.xxx   host name


这个回答缺少解释。 - Clijsters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接