LightOPC   FAQ
популярные вопросы

<<начало<<     <<LightOPC<<     [руководство]     english    

  1. Нет ли у вас какой-либо документации по OPC на русском языке?
  2. Почему не вызывается ldReadTags()?
  3. Как быть с UpdateRate?
  4. Как бы обращаться к устройствам пореже?
  5. Не получилось сделать больше XXX тэгов?
  6. Можно-ли создавать и уничтожать теги динамически?
  7. Как сделать "подсказку" для BrowseAddressSpace?
  8. Можно-ли прицепить к тегу частные данные драйвера?
  9. А зачем вообще нужен loRealTag?
  10. OPC Security?
  11. Какую ниточную модель лучше использовать?
  12. Как добиться максимальной производительности?
  13. Как быть с тестами сооответствия?
  14. Где взять Data Access Automation Wrapper?
  15. Если стандарт неоднозначен?
  16. А клиентского SDK у вас случайно нет?
  17. WinCC: "This OPC Server does not support a Browser Interface"?
  18. "lwsynch.h: No such file or directory"?

  1. Нет ли у вас какой-либо документации по OPC на русском языке?

    НЕТ.


  2. Почему не вызывается ldReadTags()?

    ldReadTags() вызывается только по запросам чтения OPC_DS_DEVICE. Обычно OPC клиенты используют только чтение из кеша OPC_DS_CACHE.

    Чтение из кеша полностю обрабатывается внутри LightOPC, поэтому драйвер должен регулярно обновлять кеш сервера через loCacheXXXXX(). Фактически, даже внутри ldReadTags(), выполнив реальное чтение, драйвер должен явно обновить кеш через loCacheXXXXX().

    Таким образом, определять ldReadTags() не обязательно. Эта функция может понадобиться для реализации чтения с побочными эффектами, а также позволяет гарантирует атомарность и очередность запросов к устройству, если это необходимо.


  3. Как быть с UpdateRate?

    Никак, вероятно. Желательно инициализировать ldRefreshRate в соответствии с производительностью вышей системы и требованиями ваших устройств. Разумный диапазон - 30...1000 мс. LightOPC вполне самостоятельно разбирается со всеми обновлениями для клиентов.

    Ваш драйвер должен поддерживать кеш актуальным и не обращать внимания на UpdateRate, запрашиваемые глупыми клиентами.

    Обычно требуетя чтобы сервер гарантировал определенную частоту опроса устройств, независящую от количества подключенных клиентов и заказанных ими частот обновления.

    Драйвер может опрашивать устройства (и обновлять кеш) с такой частотой, которая удовлетворяет вас, ваш компутер, ваши устройсва и процессы, контролируемые этими устройствами. Функция loCacheUpdate() специально сделана достаточо быстрой для использования в критичноых ко времени циклах. Она не создает непредсказуемых задержек, поскольку не блокируется на неопределенное время. Если лишний VariantCopy() кажется вам расточительством - попробуйте loCacheLock() / loCacheUnlock().

    Таким образом, частота обновлений / обращений к устройству определяется исключительно драйвером. Это позволяет драйверу правильно распределять доступную полосу пропускания между устройствами.


  4. Как бы обращаться к устройствам пореже?

    Есть две лазейки для снижения частоты опроса устройств:

    1. loDriver::ldSubscribe() позволяет отслеживать текущие активные теги;
    2. обновление по прерываниям - если, конечно устройство это допускает.
    В последнем случае желательно регулярно обновлять timestamp, поскольку кеш сохраняет время последнего изменения переменной, а кешированные данные должны казаться свежими и в отсутствие прерываний. loCacheUpdate() позволяет очень быстро изменить только timestamp для группы тегов.

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


  5. Не получилось сделать больше XXX тэгов?

    Вероятно, вы используете код
       loServiceCreate(&my_service, &ld, XXX);
    Где XXX устанавливает максимальное количество обслуживаемых тегов. Просто увеличте это число.

    Установленный предел не может быть изменен без пересоздания loService по соображениям производительности.


  6. Можно-ли создавать и уничтожать теги динамически?

    Однажды созданный тег не может быть унчтожен. Поэтому в общем случае для изменения адресного пространства сервер необходимо перезапустить. Однако...

    Наконец, сервер может быть перезапущен достаточно мягко: можно запустить несколько loService в одном процессе и заменять старый сервер новым без перезапуска процесса.

    Обычно, динамическое изменение адресного пространства сервера приносит больше вреда, чем пользы:


  7. Как сделать "подсказку" для BrowseAddressSpace?

    Определите процедуру ldAskItemId() для отображения порожденных имен на безымянные теги.

    Создайте тег "подсказку" (hint) с желаемым именем (например, "Reg[0...32727]") и пустым (NULL или VT_EMPTY) tdValue или установленным loTF_EMPTY. Этот псевдотег будет виден только через BrowseAddresSpace.

    Создайте необходимое количество безымянных тегов (tdName = NULL или "").


  8. Можно-ли прицепить к тегу частные данные драйвера?
  9. А зачем вообще нужен loRealTag?

    loRealTag определяется драйвером, а LightOPC включается его в запросы к драйверу (loTagPair::tpRt). Если драйвер имеет некоторые данные, ассоциируемые с тегом, то указатель на эти данные имеет смысл сохранить как RealTag. Можно даже определить struct loRealTag_ по вашему усмотрению. Тогда при обработке запросов вам не придется выполнять поиск тега по TagId.


  10. OPC Security?

    Следует различать интерфейс IOPCSecurity и OPC Security вообще. LightOPC позволяет реализовать многие механизмы защиты.

    Интерфейс IOPCSecurity не реализован непосредственно, поскольку он не предоставляет сколь-нибудь полезных нетривиальных услуг. Однако, он может быть реализован и включен в loClient через loClientChain().

    Любая "защита" строится из аутентификации и авторизации. IOPCSecurity не предусматривает авторизацию (т.е. не сопоставлят права доступа и пользователей).

    В простейшем случае вы можете поделить ваши теги на несколько групп и обслуживать их разными серверами с разной DCOM авторизацией. Эти серверы могут исполняться в одном процессе.

    Чтобы ввести в ваш сервер защиту на уровне отдельных тегов необходимо:

    1. Поймать клиентский запрос.
      Вы можете фильтровать такие запросы:
      • Любую попытку записи - через ldWriteTags().
      • Чтение из устройства - через ldReadTags().
      • Добавление тега клиентом - через ldAskItemId() & loDF_CHECKITEM / loTF_CHECKITEM. В этом случае вы можете запретить любой доступ к тегу (и к кешу, и к устройству) для определенных комбинаций тег - клиент.
    2. Опознать клиента. Есть несколько способов:
      • Получить контекст вызова, пользуясь обычными средствами DCOM.
      • Проверить access_path тега на предмет волшебного слова.
      • Сделать 2 (userid / password) или даже 3 (challenge / userid / response) дополнительных тега. Клиент должен корректно их инициализировать чтобы получить доступ ко всему остальному.
    3. Проверить полномочия и удовлетворить или отвергнуть запрос. Можно использовать средства NT (которые довольно медлительны при 100 и более пользователях) или ваши собственные ACL.
    И всего-то!
  11. Какую ниточную модель лучше использовать?

    Ох... Сам по себе LightOPC "свободен" аки птиц.

    Для exe-серверов существенна инициализация нитки, обслуживающей фабрику классов. IMHO, COINIT_MULTITHREADED предпочтительней. Использовать COINIT_APARTMENTTHREADED тоже можно, но такая нитка должна обрабатывать оконные сообщения. Кроме того, полезно в loDriver::ldFlags установить флаги (loDf_BOTHMODEL | loDf_FREEMARSH) вместо loDf_FREEMODEL.

    Для того, чтобы показывать приличную производительность в комбинации in-proc сервера с однониточным клиентом имеется поддержка модели both. Эта модель должна быть разрешена при компиляции (LO_USE_BOTHMODEL и LO_USE_FREEMARSHALL) и при исполнении (loDf_BOTHMODEL и loDf_FREEMARSH). Поскольку both модель тормозит многониточных клиентов ее поддержку можно включать для отдельных клиентов.

    loDf_BOTHMODEL приводит к использованию локальных message loop в процедурах синхронизации ниток, что в общем случае плохо сказывается на надежности сервера.


  12. Как добиться максимальной производительности?

    Вы действительно недовольны бенчмарками?

    1. Очень сильно тормозит EventLog. Можно уменьшить уровень журнализации или перенаправить журналы в файлы. См. README.txt про настройки unilog.
    2. Если используется очень много именованных тегов попытайтесь заменить их безымянными с "подсказками".
    3. Для in-proc сервера выберите правильную ниточную модель.
    4. Попытайтесь заставить клиентов работать с каноническими типами.
    5. Увеличте ldRefreshRate и сделайте его кратным гранулярности часов системного планировщика.
    6. Запретите loDF_IGNCASE, xmalloc() & Co, LO_USE_OBJXREF.
    7. Можно попытаться запретить проверку OPC_READABLE / OPC_WRITEABLE через LO_CHECK_RIGHTS, но это помогает не сильно.

  13. Как быть с тестами сооответствия?
  14. Где взять Data Access Automation Wrapper?

    Мы не являемся членом OPC Foundation и, вероятно, никогда им не станем. Поэтому ни Automation Wrapper DLL, ни тестов соответствия у нас нет.

    Скомпилированный opcXXXauto.dll имеется в демонстрационных пакетах многих производителей. В частности, Matrikon Explorer & Simulator, KEPware, etc.

    LightOPC прекрасно работает с такими Automation конвертерами.


  15. Если стандарт неоднозначен?
  16. А клиентского SDK у вас случайно нет?

    Нет.
    IMHO, OPC описывает именно клиентский API и писать клиентов на чистом OPC достаточно просто. Дальнейшее упрощение интерфейса приведет только к сокращению функциональности.

    Посмотите следующие ссылки:


  17. WinCC: "This OPC Server does not support a Browser Interface"?

    Перед вызовом loServiceCreate() установите loDriver::ldRefreshRate равным 1 или иному значению, дольному 1000 мс.
    Подробности о ldRefreshRate см. в lightopc.h и руководстве.


  18. "lwsynch.h: No such file or directory"?

    ftp://ftp.ipi.ac.ru/pub/LightOPC/ unilog-current.tgz



Пишите:     master AT ipi ac ru