首页 > 解决方案 > 使用 Eclipse Milo 连接到 OPC-UA 服务器在 BadHostUnknown 上失败

问题描述

我是 OPC-UA 和 Eclipse Milo 的新手,我正在尝试构建一个可以连接到我们刚刚购买的机器的 OPC-UA 服务器的客户端。

通过使用以下 Python 教程系列,我已经能够在我的笔记本电脑上设置一个简单的 OPC-UA 服务器: https: //www.youtube.com/watch?v=NbKeBfK3pfk。此外,我已经能够使用 Eclipse Milo 示例成功运行订阅示例以从该服务器读取一些值。

但是,我在连接到我们刚刚收到的机器的 OPC-UA 服务器时遇到了困难。我已经使用 UaExpert 客户端成功连接到该服务器,但我们想使用 Eclipse Milo 构建自己的客户端。我可以看到在使用 UaExpert 连接到服务器时出现了一些警告,这些警告似乎提供了有关该问题的线索,但我在服务器-客户端通信/OPC-UA 方面的经验太少,希望能得到一些帮助。我将解释当我使用 UaExpert 客户端时会发生什么,因为我一直在使用它来尝试诊断正在发生的事情。

我注意到,当我第一次启动 UaExpert 时,我收到以下可能相关的错误:

Discovery FindServersOnNetwork on opc.tcp://localhost:4840 failed (BadTimeout), falling back to FindServers
Discovery FindServers on opc.tpc://localhost:4840 failed (BadTimeout)
Discovery GetEndpoints on opc.tcp://localhost:4840 failed

我对网络真的很陌生,所以不确定这到底意味着什么。

我将概述我在尝试使 Eclipse Milo 的 SubscriptionExample 与这台机器的服务器一起工作时所遵循的过程。首先,我将 getEndpointUrl() 方法更改为我们正在使用的设备的 IP 地址:return "opc.tcp://11.23.1.1:4840"。我可以使用笔记本电脑上的 ping 11.23.1.1 成功 ping 设备。当我尝试使用此地址运行 SubscriptionExample 时,出现以下错误:

[NonceUtilSecureRandom] INFO  o.e.m.o.stack.core.util.NonceUtil - SecureRandom seeded in 0ms.
18:36:23.879 [main] ERROR o.e.m.e.client.ClientExampleRunner - Error running client example: java.net.UnknownHostException: br-automation
java.util.concurrent.ExecutionException: java.net.UnknownHostException: br-automation
    at java.util.concurrent.CompletableFuture.reportGet(Unknown Source)
    at java.util.concurrent.CompletableFuture.get(Unknown Source)
    at org.eclipse.milo.examples.client.SubscriptionExample.run(SubscriptionExample.java:50)
    at org.eclipse.milo.examples.client.ClientExampleRunner.run(ClientExampleRunner.java:120)
    at org.eclipse.milo.examples.client.SubscriptionExample.main(SubscriptionExample.java:42)
Caused by: java.net.UnknownHostException: br-automation
    at java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method)
    at java.net.InetAddress$2.lookupAllHostAddr(Unknown Source)
    at java.net.InetAddress.getAddressesFromNameService(Unknown Source)
    at java.net.InetAddress.getAllByName0(Unknown Source)
    at java.net.InetAddress.getAllByName(Unknown Source)
    at java.net.InetAddress.getAllByName(Unknown Source)
    at java.net.InetAddress.getByName(Unknown Source)
    at io.netty.util.internal.SocketUtils$8.run(SocketUtils.java:148)
    at io.netty.util.internal.SocketUtils$8.run(SocketUtils.java:145)
    at java.security.AccessController.doPrivileged(Native Method)
    at io.netty.util.internal.SocketUtils.addressByName(SocketUtils.java:145)
    at io.netty.resolver.DefaultNameResolver.doResolve(DefaultNameResolver.java:43)
    at io.netty.resolver.SimpleNameResolver.resolve(SimpleNameResolver.java:63)
    at io.netty.resolver.SimpleNameResolver.resolve(SimpleNameResolver.java:55)
    at io.netty.resolver.InetSocketAddressResolver.doResolve(InetSocketAddressResolver.java:57)
    at io.netty.resolver.InetSocketAddressResolver.doResolve(InetSocketAddressResolver.java:32)
    at io.netty.resolver.AbstractAddressResolver.resolve(AbstractAddressResolver.java:108)
    at io.netty.bootstrap.Bootstrap.doResolveAndConnect0(Bootstrap.java:200)
    at io.netty.bootstrap.Bootstrap.access$000(Bootstrap.java:46)
    at io.netty.bootstrap.Bootstrap$1.operationComplete(Bootstrap.java:180)
    at io.netty.bootstrap.Bootstrap$1.operationComplete(Bootstrap.java:166)
    at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:577)
    at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:551)
    at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:490)
    at io.netty.util.concurrent.DefaultPromise.setValue0(DefaultPromise.java:615)
    at io.netty.util.concurrent.DefaultPromise.setSuccess0(DefaultPromise.java:604)
    at io.netty.util.concurrent.DefaultPromise.trySuccess(DefaultPromise.java:104)
    at io.netty.channel.DefaultChannelPromise.trySuccess(DefaultChannelPromise.java:84)
    at io.netty.channel.AbstractChannel$AbstractUnsafe.safeSetSuccess(AbstractChannel.java:984)
    at io.netty.channel.AbstractChannel$AbstractUnsafe.register0(AbstractChannel.java:504)
    at io.netty.channel.AbstractChannel$AbstractUnsafe.access$200(AbstractChannel.java:417)
    at io.netty.channel.AbstractChannel$AbstractUnsafe$1.run(AbstractChannel.java:474)
    at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500)
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    at java.lang.Thread.run(Unknown Source)
18:36:23.881 [ForkJoinPool.commonPool-worker-1] ERROR o.e.m.e.client.ClientExampleRunner - Error running example: java.net.UnknownHostException: br-automation
java.util.concurrent.ExecutionException: java.net.UnknownHostException: br-automation
    at java.util.concurrent.CompletableFuture.reportGet(Unknown Source)
    at java.util.concurrent.CompletableFuture.get(Unknown Source)
    at org.eclipse.milo.examples.client.SubscriptionExample.run(SubscriptionExample.java:50)
    at org.eclipse.milo.examples.client.ClientExampleRunner.run(ClientExampleRunner.java:120)
    at org.eclipse.milo.examples.client.SubscriptionExample.main(SubscriptionExample.java:42)
Caused by: java.net.UnknownHostException: br-automation
    at java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method)
    at java.net.InetAddress$2.lookupAllHostAddr(Unknown Source)
    at java.net.InetAddress.getAddressesFromNameService(Unknown Source)
    at java.net.InetAddress.getAllByName0(Unknown Source)
    at java.net.InetAddress.getAllByName(Unknown Source)
    at java.net.InetAddress.getAllByName(Unknown Source)
    at java.net.InetAddress.getByName(Unknown Source)
    at io.netty.util.internal.SocketUtils$8.run(SocketUtils.java:148)
    at io.netty.util.internal.SocketUtils$8.run(SocketUtils.java:145)
    at java.security.AccessController.doPrivileged(Native Method)
    at io.netty.util.internal.SocketUtils.addressByName(SocketUtils.java:145)
    at io.netty.resolver.DefaultNameResolver.doResolve(DefaultNameResolver.java:43)
    at io.netty.resolver.SimpleNameResolver.resolve(SimpleNameResolver.java:63)
    at io.netty.resolver.SimpleNameResolver.resolve(SimpleNameResolver.java:55)
    at io.netty.resolver.InetSocketAddressResolver.doResolve(InetSocketAddressResolver.java:57)
    at io.netty.resolver.InetSocketAddressResolver.doResolve(InetSocketAddressResolver.java:32)
    at io.netty.resolver.AbstractAddressResolver.resolve(AbstractAddressResolver.java:108)
    at io.netty.bootstrap.Bootstrap.doResolveAndConnect0(Bootstrap.java:200)
    at io.netty.bootstrap.Bootstrap.access$000(Bootstrap.java:46)
    at io.netty.bootstrap.Bootstrap$1.operationComplete(Bootstrap.java:180)
    at io.netty.bootstrap.Bootstrap$1.operationComplete(Bootstrap.java:166)
    at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:577)
    at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:551)
    at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:490)
    at io.netty.util.concurrent.DefaultPromise.setValue0(DefaultPromise.java:615)
    at io.netty.util.concurrent.DefaultPromise.setSuccess0(DefaultPromise.java:604)
    at io.netty.util.concurrent.DefaultPromise.trySuccess(DefaultPromise.java:104)
    at io.netty.channel.DefaultChannelPromise.trySuccess(DefaultChannelPromise.java:84)
    at io.netty.channel.AbstractChannel$AbstractUnsafe.safeSetSuccess(AbstractChannel.java:984)
    at io.netty.channel.AbstractChannel$AbstractUnsafe.register0(AbstractChannel.java:504)
    at io.netty.channel.AbstractChannel$AbstractUnsafe.access$200(AbstractChannel.java:417)
    at io.netty.channel.AbstractChannel$AbstractUnsafe$1.run(AbstractChannel.java:474)
    at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500)
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    at java.lang.Thread.run(Unknown Source)

使用 UaExpert 时,“opc.tcp://11.23.1.1:4840”是我在使用自定义发现时添加新服务器时输入的服务器地址。当我输入此内容时,一个设备显示为该服务器的下拉列表,称为 B&R Embedded OPC-UA Server,因为 OPC-UA 服务器托管在机器中的 B&R 设备上。当我选择此设备进行连接时,我收到以下消息:

用于调用 GetEndpoints (br-automation) 的发现 URL 的主机名已替换为用于调用 FindServers (11.23.1.1) 的主机名。您还想用此主机名替换 EndpointURL 的主机名吗?

我必须接受此消息才能找到服务器,但我对到底发生了什么感到困惑。我假设用于查找服务器的端点和用于其他用途的端点存在差异?我发现网上的资源很难理解。在 UaExpert 日志中,连续三行日志报告“正在添加 URL:ocp.tcp://br-automation:4840”。然后它还会报告端点:“ocp.tcp://br-automation:4840”、应用程序 Uri 和安全策略(无)。如果我尝试将客户端的 getEndpointUrl 方法中的地址更改为 ocp.tcp://br-automation:4840 ,则会收到以下错误:

[main] INFO  o.e.m.opcua.sdk.client.OpcUaClient - Eclipse Milo OPC UA Client SDK version: 0.4.3-SNAPSHOT
18:37:46.035 [main] ERROR o.e.m.e.client.ClientExampleRunner - Error getting client: java.util.concurrent.ExecutionException: java.net.UnknownHostException: br-automation
org.eclipse.milo.opcua.stack.core.UaException: java.util.concurrent.ExecutionException: java.net.UnknownHostException: br-automation
    at org.eclipse.milo.opcua.sdk.client.OpcUaClient.lambda$create$1(OpcUaClient.java:204)
    at java.util.Optional.orElseGet(Unknown Source)
    at org.eclipse.milo.opcua.sdk.client.OpcUaClient.create(OpcUaClient.java:204)
    at org.eclipse.milo.opcua.sdk.client.OpcUaClient.create(OpcUaClient.java:201)
    at org.eclipse.milo.examples.client.ClientExampleRunner.createClient(ClientExampleRunner.java:73)
    at org.eclipse.milo.examples.client.ClientExampleRunner.run(ClientExampleRunner.java:94)
    at org.eclipse.milo.examples.client.SubscriptionExample.main(SubscriptionExample.java:42)
Caused by: java.util.concurrent.ExecutionException: java.net.UnknownHostException: br-automation
    at java.util.concurrent.CompletableFuture.reportGet(Unknown Source)
    at java.util.concurrent.CompletableFuture.get(Unknown Source)
    at org.eclipse.milo.opcua.sdk.client.OpcUaClient.create(OpcUaClient.java:180)
    ... 4 common frames omitted
Caused by: java.net.UnknownHostException: br-automation
    at java.net.InetAddress.getAllByName0(Unknown Source)
    at java.net.InetAddress.getAllByName(Unknown Source)
    at java.net.InetAddress.getAllByName(Unknown Source)
    at java.net.InetAddress.getByName(Unknown Source)
    at io.netty.util.internal.SocketUtils$8.run(SocketUtils.java:148)
    at io.netty.util.internal.SocketUtils$8.run(SocketUtils.java:145)
    at java.security.AccessController.doPrivileged(Native Method)
    at io.netty.util.internal.SocketUtils.addressByName(SocketUtils.java:145)
    at io.netty.resolver.DefaultNameResolver.doResolve(DefaultNameResolver.java:43)
    at io.netty.resolver.SimpleNameResolver.resolve(SimpleNameResolver.java:63)
    at io.netty.resolver.SimpleNameResolver.resolve(SimpleNameResolver.java:55)
    at io.netty.resolver.InetSocketAddressResolver.doResolve(InetSocketAddressResolver.java:57)
    at io.netty.resolver.InetSocketAddressResolver.doResolve(InetSocketAddressResolver.java:32)
    at io.netty.resolver.AbstractAddressResolver.resolve(AbstractAddressResolver.java:108)
    at io.netty.bootstrap.Bootstrap.doResolveAndConnect0(Bootstrap.java:200)
    at io.netty.bootstrap.Bootstrap.access$000(Bootstrap.java:46)
    at io.netty.bootstrap.Bootstrap$1.operationComplete(Bootstrap.java:180)
    at io.netty.bootstrap.Bootstrap$1.operationComplete(Bootstrap.java:166)
    at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:577)
    at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:551)
    at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:490)
    at io.netty.util.concurrent.DefaultPromise.setValue0(DefaultPromise.java:615)
    at io.netty.util.concurrent.DefaultPromise.setSuccess0(DefaultPromise.java:604)
    at io.netty.util.concurrent.DefaultPromise.trySuccess(DefaultPromise.java:104)
    at io.netty.channel.DefaultChannelPromise.trySuccess(DefaultChannelPromise.java:84)
    at io.netty.channel.AbstractChannel$AbstractUnsafe.safeSetSuccess(AbstractChannel.java:984)
    at io.netty.channel.AbstractChannel$AbstractUnsafe.register0(AbstractChannel.java:504)
    at io.netty.channel.AbstractChannel$AbstractUnsafe.access$200(AbstractChannel.java:417)
    at io.netty.channel.AbstractChannel$AbstractUnsafe$1.run(AbstractChannel.java:474)
    at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500)
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    at java.lang.Thread.run(Unknown Source)

我不知道这是否足以诊断问题的信息,但如果我能帮助我让 Eclipse Milo 服务器执行相同的过程并连接到机器的服务器,我将不胜感激。

标签: eclipseopc-uamilo

解决方案


问题是您运行客户端的计算机无法将主机名“br-automation”解析为 IP 地址。

如果您无法将服务器配置为返回 IP 地址,则解决方案是手动重建EndpointDescription从 GetEndpoints 服务调用获得的 s,以便它们具有包含 IP 地址而不是主机名的端点 URL。这就是 UaExpert 在警告您更换主机名时在幕后所做的事情。

您可以在它被传递给 OpcUaClientConfig 之前使用它EndpointUtil#updateUrl来构建一个新的。EndpointDescription


推荐阅读