Не удается подключиться к серверу OPC-UA с помощью Eclipse Milo на BadHostUnknown

Я новичок в OPC-UA и Eclipse Milo, и я пытаюсь создать клиента, который может подключаться к серверу OPC-UA машины, которую мы только что приобрели.

Мне удалось настроить простой сервер OPC-UA на своем ноутбуке с помощью этой серии руководств по Python: 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

Я новичок в сетевых технологиях, поэтому не совсем понимаю, что это значит.

Я опишу процесс, которым я следовал, пытаясь получить SubscriptionExample для Eclipse Milo, работающего с сервером этой машины. Во-первых, я меняю метод getEndpointUrl () на IP-адрес устройства, которое мы используем: return opc.tcp: //11.23.1.1: 4840. Я могу успешно пропинговать устройство с помощью ping 11.23.1.1 со своего ноутбука. Когда я пытаюсь запустить 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 - это адрес сервера, который я ввожу при добавлении нового сервера при использовании Custom Discovery. Когда я ввожу это, устройство появляется в раскрывающемся списке этого сервера под названием B&R Embedded OPC-UA Server, поскольку сервер OPC-UA размещен на устройстве B&R в машине. Когда я выбираю это устройство для подключения, я получаю следующее сообщение:

Имя хоста URL обнаружения, используемого для вызова GetEndpoints (br-automation), было заменено именем хоста, используемым для вызова FindServers (11.23.1.1). Вы также хотите заменить имена хостов EndpointURL на это имя хоста?

Я должен принять это сообщение, чтобы сервер был найден, но я не совсем понимаю, что происходит. Я предполагаю, что есть разница в конечной точке, используемой для поиска сервера, и конечной точке, используемой для чего-то еще? Я обнаружил, что ресурсы в Интернете очень трудны для понимания. В журналах UaExpert есть три строки журналов подряд, в которых указывается Adding 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 выполнять тот же процесс и подключаться к серверу машины.


person Alex C    schedule 10.08.2020    source источник


Ответы (3)


Проблема в том, что компьютер, на котором запущен клиент, не может преобразовать имя хоста br-automation в IP-адрес.

Решение, если вы не можете настроить свой сервер для возврата IP-адреса, состоит в том, чтобы вручную перестроить EndpointDescription, которые вы получаете от вызова службы GetEndpoints, чтобы у них был URL-адрес конечной точки, содержащий IP-адрес вместо имени хоста. Это то, что делает UaExpert за кулисами, когда предупреждает вас о замене имени хоста.

Вы можете использовать EndpointUtil#updateUrl для создания нового EndpointDescription, прежде чем он будет передан в OpcUaClientConfig.

person Kevin Herron    schedule 10.08.2020
comment
Отлично, большое спасибо за помощь, Кевин - удалось подключить его! Есть ли причина, по которой сервер будет возвращать это имя хоста вместо IP-адреса, или вы не можете точно сказать? - person Alex C; 11.08.2020
comment
Обычно это происходит из-за неправильной настройки. Я уверен, что это фактическое имя хоста сервера, но, учитывая, что вы не можете разрешить это имя хоста с помощью DNS, сервер также должен быть настроен для возврата IP-адресов. - person Kevin Herron; 11.08.2020
comment
@KevinHerron Кевин, не могли бы вы привести простой пример того, как восстановить EndpointDescriptions - person not a Programmer; 09.11.2020

Вы можете найти правильное имя хоста / URL-адрес для подключения к серверу, используя журнал сервера. После запуска журналов сервера он распечатывает все действительные UR

person user432843    schedule 11.09.2020

Мы смогли решить нашу проблему, вручную перезаписав имя хоста, возвращаемое с сервера OPC UA, IP-адресом и портом хоста. (см. вторую строку оператора try)

public class OpcUaConnection {
    OpcUaClient client;
    final int NAMESPACEINDEX = 6;

    private static final AtomicLong clientHandles = new AtomicLong(1L);

    public OpcUaConnection() {
        try {
            List<EndpointDescription> endpoints = DiscoveryClient.getEndpoints("opc.tcp://192.168.0.122:4840").get();
            EndpointDescription configPoint = EndpointUtil.updateUrl(endpoints.get(0), "192.168.0.122", 4840);

            OpcUaClientConfigBuilder cfg = new OpcUaClientConfigBuilder();
            cfg.setEndpoint(configPoint);

            this.client = OpcUaClient.create(cfg.build());
            client.connect().get();

        } catch (Throwable ex) {
            ex.printStackTrace();
        }
    }

Надеюсь, это поможет другим!

person Michael Simonsen    schedule 10.11.2020