OPC UA ServiceResultException (BadSecureChannelClosed) обновление конечной точки с сервера

Мое приложение C# использует стек OPC UA Core в качестве клиента для подключения к ПЛК, работающему в качестве сервера. Я не использую OPC UA SDK, потому что приложение WPF, а SDK непонятен.

Я ознакомился с различными справочными материалами (включая OPC UA SDK и Converter Systems LLC набор инструментов WPF). ) и собрал собственный метод настройки объекта ITransportChannel для передачи конструктору Opc.UaSessionClient.

Проблема, с которой я столкнулся, заключается в том, что для получения описания и конфигурации конечной точки, которые соответствуют ожидаемым значениям сервера, я использую ConfiguredEndpoint.UpdateFromServer, но это выдает ServiceResultException(BadSecureChannelClosed), когда его объект DiscoveryClient закрывается.

Я не вижу, чтобы об этом исключении сообщал проект SimpleOpClient, включенный в SDK (что никоим образом не просто).

Любые идеи, что может быть не так с этой функцией?

    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? Если да, то почему? Или это одно из множества внутренних исключений, выбрасываемых стеком?


person Evil Dog Pie    schedule 09.06.2016    source источник


Ответы (1)


Во-первых, ваш код работает нормально. Он обновляет конечную точку, даже если выдает это исключение. Это обрабатываемое исключение библиотеки opc.ua.core всякий раз, когда библиотека закрывает сокет. Вы увидите его в отладчике, если вы выбрали «Все исключения общеязыковой среды выполнения, не входящие в этот список» в окне «Настройки исключений».

Во-вторых, те из нас, кто использует код OPC Foundation на UA-.NET, будут рады узнать, что Конструктор Session.Create() автоматически обновит конечные точки, если параметр имеет значение true. См. этот пост для примера. OPC UA: минимальный код, просматривающий корневой узел сервера

Кроме того, поскольку вы нашли мой оригинальный набор инструментов WPF, я хотел бы пригласить вас в мой новый и улучшенный WPF и набор инструментов UAP. размещен на GitHub.

person Andrew Cullen    schedule 30.06.2016
comment
Новый инструментарий выглядит великолепно, и я был бы очень рад его использовать, если бы моему приложению требовалась значительная часть функционала. Первоначальный был чрезвычайно полезен для меня как способ понять, какие части SDK необходимы, а какие я могу потерять. - person Evil Dog Pie; 30.06.2016
comment
Моему приложению требуется всего несколько функций (после открытия сеанса): оно считывает массив из восьми целых чисел Int16 до 40 раз в секунду, опрашивает «счетчик тиков» в качестве сердцебиения один раз в секунду и иногда записывает Boolean для включения удаленный вызов процедуры. Это делает 90% SDK избыточным. Я собрал действительно простой клиент, используя только OPC UA Core примерно в 2000 строк кода. - person Evil Dog Pie; 30.06.2016
comment
Одно из самых больших разочарований, связанных с SDK и стеком (в отличие от вашего инструментария), заключается в том, что они, по-видимому, используют исключения в качестве механизма для возврата условий ошибки. Очень немногие из них на самом деле указывают на то, что что-то стало непригодным для использования, поэтому клиентский код загромождается try...catch блоками, которые в основном ничего не делают, кроме как игнорируют исключение. - person Evil Dog Pie; 30.06.2016
comment
если параметр верный. Какой параметр? updateBeforeConnect? - person astrowalker; 21.11.2016