2016-11-11 7 views
3

Я использую Java OPC-UA client Eclipse Milo. Всякий раз, когда я создаю сеанс с использованием конечного URL-адреса сервера, метод UaTcpStackClient.getEndpoints() изменяет URL-адрес на localhost.Java-клиент OPC-UA Eclipse URL-адрес конечной точки Milo для localhost

String endpointUrl = "opc.tcp://10.8.0.104:48809"; 

EndpointDescription[] endpoints = UaTcpStackClient.getEndpoints(endpointUrl).get(); 

EndpointDescription endpoint = Arrays.stream(endpoints) 
      .filter(e -> e.getSecurityPolicyUri().equals(securityPolicy.getSecurityPolicyUri())) 
      .findFirst().orElseThrow(() -> new Exception("no desired endpoints returned")); 

Однако значение endpoint.getEndpointUrl() возвращает opc.tcp://127.0.0.1:4880/, что приводит сбой в связи.

Я понятия не имею, почему изменился мой URL-адрес OPC?

ответ

2

Это довольно распространенная проблема при реализации клиента UA.

Сервер, в конечном счете, несет ответственность за содержимое конечных точек, которые вы возвращаете, и тот, с которым вы подключаетесь, является (неправильно) настроен для возврата 127.0.0.1 на конечные URL-адреса, по-видимому.

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

В любом случае вам необходимо создать новый набор EndpointDescription s, в котором вы исправили URL-адрес, прежде чем приступать к созданию OpcUaClient.

Альтернативно ... вы можете выяснить, как правильно настроить ваш сервер, чтобы он возвращал конечные точки, содержащие общедоступное имя хоста или IP-адрес.

Update:

Код для замены конечной точки URL может быть некоторые вариации этого:

private static EndpointDescription updateEndpointUrl(
    EndpointDescription original, String hostname) throws URISyntaxException { 

    URI uri = new URI(original.getEndpointUrl()).parseServerAuthority(); 

    String endpointUrl = String.format(
     "%s://%s:%s%s", 
     uri.getScheme(), 
     hostname, 
     uri.getPort(), 
     uri.getPath() 
    ); 

    return new EndpointDescription(
     endpointUrl, 
     original.getServer(), 
     original.getServerCertificate(), 
     original.getSecurityMode(), 
     original.getSecurityPolicyUri(), 
     original.getUserIdentityTokens(), 
     original.getTransportProfileUri(), 
     original.getSecurityLevel() 
    ); 
} 

Оговорка: это работает в большинстве случаев, но один примечательный случай, он не работает то, когда URL удаленной конечной точки содержит символы, которые не разрешены в имени хоста URL (в соответствии с RFC), например, подчеркивание (a '_'), которое, к сожалению, разрешено, например, имя хоста машины Windows. Поэтому вам может понадобиться использовать другой метод анализа URL-адреса конечной точки, а не полагаться на класс URI, чтобы сделать это.

+0

спасибо за ответ Кевин, я понимаю, что вы пытаетесь сказать .. как я могу создать новый набор EndpointDescriptions, я не вижу никаких способов или методов setter для него –

+0

Я добавил некоторый пример кода. –

+0

спасибо @kevin Herron –