Как стать автором
Обновить

Шпаргалка по OPC DA 2 в .NET

Время на прочтение4 мин
Количество просмотров58K
На днях пришлось крепко повозиться с настройкой вызова удалённого сервера по протоколу OPC DA 2.05a, и эта информация бы очень пригодилась, знай я её заранее.

1. Что такое OPC DA и в частности OPC DA 2.05a


В общем случае OPC — это набор открытых протоколов, регламентирующих взаимодействие между собой различных объектов автоматизации, таких как SCADA-системы, к примеру. OPC DA (Data Access) — это один из таких протоколов, он обеспечивает обмен данными с устройствами или программными компонентами. В моем случае по этому протоколу нужно было периодически забирать данные со SCADA-системы. И самое важное — OPC DA работает на базе технологии COM, так что взаимодействие с OPC сервером по сути сводится к взаимодействию с COM сервером.

2. Какие есть библиотеки



Бинарники от Opc Foundation

Называются OPC .NET API 2.00 Redistributable — их нельзя скачать просто так, нужно быть «мембером» (= зарегиться и занести деньжат). Там же и OPC Core Components, от которых эта библиотека зависит. На рутрекере можно найти и то, и другое. А вообще не совсем понятно, почему для получения библиотеки от Opc Foundation — компании, которая продвигает «открытый стандарт» — нужно что-то платить.
Что могу сказать по поводу этой библиотеки. Документации к ней нигде нет, и API построен не самым лучшим образом (например есть несколько интерфейсов и классов с одним и тем же именем, но в разных пространствах имен, жутко неудобно, постоянно нужно лезть в Object Browser и смотреть, какой именно класс нужен), однако функциональности полно — можно что угодно сделать, что только можно сделать с OPC серверами. Кстати, я для удобства прогнал сборки рефлектором и работал уже с исходниками — все проблемы декомпиляции по счастливой случайности возникли в других протоколах (OPC AE, OPC HDA) и я их просто выкинул за ненадобностью. Могу прислать солюшен, если кому интересно, пишите.

Компоненты от Advasol

Платные компоненты (причем весьма дорогие). Скачал я Evaluation версию — инсталлятор, который потребовал пароль (!), ну а пароль пришел по почте. Самое полезное в этом наборе компонент — тестовые клиенты для OPC — winforms приложения, позволяющие попробовать приконнектиться и посмотреть, что есть внутри OPC сервера. Сами библиотеки я не смотрел, они обфусцированы и в них заложено ограничение по времени — полчаса, потом программу надо перезапускать. Но с тестовым клиентом возился долго, так как система у меня была 64битная, а сборка тестового клиента, как оказалось, собрана под Target Platform = AnyCPU, и в 32битной винде запускалась как 32битное приложение (и все работало как надо), а в 64битной — как 64битное. Что приводило к ошибке в коде COM-интеропа вида «CLSID is not registered». А я думал, что у меня что-то неправильно настроено и 2 дня убил на копания в secpol.msc, dcomcnfg и compmgmt.msc. По счастливой случайности догадался запустить клиент с другой тачки и все стало ясно. С помощью ILDASM и Hex-редактора определил смещение флага TargetPlatform (от начала CLR Header), добавил туда второй бит 32BITREQUIRED и все заработало. Вывод — если у вас не работает COM Interop, первым делом проверьте соответствие платформы. К слову, клиент тоже был обфусцирован (с помощью SmartAssembly), и его CLR Header был расположен в конце.

Библиотека OPCDOTNET

Библиотека от энтузиаста на codeproject.com. Ничего не могу сказать, но именно её код использовал мой предшественник, который реализовал локальное взаимодействие с OPC сервером. Судя по тому, что написано в статье, она как раз для локального взаимодействия и предназначена. Плюсы — доступные исходники, наличие тестового клиента, отсутствие зависимостей.

3. Можно ли написать код без использования библиотек


В принципе, ничего сложного в этом нет, если вы имели опыт взаимодействия с COM/DCOM приложениями. А тем, кто как и я, не особо разбирается в этих технологиях, могу порекомендовать писать код, поглядывая на декомпилированные исходники библиотеки от OPC Foundation. По сути, для взаимодействия с OPC сервером достаточно всего лишь сделать интеропы на необходимые интерфейсы, получить их и дергать методы.

4. Проблемы


— Тестовый клиент не подключается с ошибкой RPC сервер недоступен — проверьте доступность портов, порта номер 135 как минимум (основной порт DCOM).

— Access Denied — придется повозиться с настройкой как сервера, так и клиента. См. ссылки внизу

— CLSID is not registered — проверьте, установлен ли у вас Core Components, возможно их не хватает. Либо проверьте Target Platform сборки, осуществляющей интероп. Может быть, там AnyCPU а должно быть x86.

— CoCreateInstanceEx возвращает валидный COM объект, но при касте его к COM интерфейсам вываливается Access Denied (0x80070001). С этой проблемой я возился полдня. Эта штука происходит, когда для доступа к серверу необходимо указать юзера и пароль. Вы вызываете CoCreateInstanceEx, заполнив перед этим SERVER_INFO, и вам приходит ссылка на объект. Однако следующие вызовы QueryInterface не сохраняют параметров доступа, которые вы указали при получении объекта, и это приводит к Access Denied. Решение — вызвать магическую функцию CoInitializeSecurity, которая установит дефолтные параметры безопасности для COM-вызовов. Код:

[DllImport("ole32.dll")]
private static extern int CoInitializeSecurity(IntPtr pSecDesc, int cAuthSvc,
    SOLE_AUTHENTICATION_SERVICE[] asAuthSvc, IntPtr pReserved1,
    uint dwAuthnLevel, uint dwImpLevel, IntPtr pAuthList,
    uint dwCapabilities, IntPtr pReserved3);

public static void InitializeSecurity() {
    int errorCode = CoInitializeSecurity(IntPtr.Zero, -1, null, IntPtr.Zero, 1, 2,
        IntPtr.Zero, 0, IntPtr.Zero);
    if (errorCode != 0) {
        throw new ExternalException("CoInitializeSecurity: " +
            GetSystemMessage(errorCode), errorCode);
    }
}


При вызове этой функции может случиться ошибка RPC_E_TOO_LATE. Эта ошибка возникает обычно из-за хост-процесса Visual Studio, который неявно вызывает CoInitializeSecurity при старте. Для решения проблемы достаточно отключить использование хост-процесса в настройках проекта.

По этой проблеме есть несколько ссылок с полезной информацией:
Как чел с stackoverflow сам себе помог разобраться
Готовые интеропы функции с ремарками
Предложения майрософту от разработчиков по этой проблеме

5. Ссылки по теме


OPC Training Institute — сайт с множеством отлично оформленных статей, которые помогают в случае проблем. Например, как настроить DCOM, какие возможные причины ошибки RPC server is not available итд. Требует регистрации, регистрация бесплатна.

Туториалы по настройке DCOM — еще 1 хорошо оформленный туториал для настройки.
Теги:
Хабы:
Всего голосов 10: ↑8 и ↓2+6
Комментарии4

Публикации

Истории

Работа

.NET разработчик
45 вакансий

Ближайшие события

7 – 8 ноября
Конференция byteoilgas_conf 2024
МоскваОнлайн
7 – 8 ноября
Конференция «Матемаркетинг»
МоскваОнлайн
15 – 16 ноября
IT-конференция Merge Skolkovo
Москва
22 – 24 ноября
Хакатон «AgroCode Hack Genetics'24»
Онлайн
28 ноября
Конференция «TechRec: ITHR CAMPUS»
МоскваОнлайн
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань