Взаимодействие между базами 1С через COM

В этой статье я расскажу о многих особенностях взаимодействия между базами 1С по COM технологии, накопленных за годы развития и использования интеграционного коммерческого продукта 2iS:Интеграция нашей компании 2iS.

В этой статье я расскажу о многих особенностях взаимодействия между базами 1С по COM технологии, накопленных за годы развития и использования интеграционного коммерческого продукта 2iS:Интеграция нашей компании 2iS.

Термины

ОС – операционная система 

COM-клиент – процесс(поток) ОС, запросивший создание COM-объекта

COM-сервер – COM-объект, созданный по запросу клиента

Com-соединитель – COM-объект V8X.ComСonnector для создания внешних соединений с базами 1С

Automation-сервер – он же OLE-сервер, COM-объект V8X.Application для создания приложений 1С

Издание платформы – подстрока до 2-й точки версии платформы (например 8.2, 8.3)

Сборка платформы – полная строка версии платформы (например 8.2.19.130, 8.2.16.352)

Подключение внешнего соединения

Рассмотрим алгоритм подключения внешнего соединения в деталях

  1. Создание COM-объекта Com-соединитель (Имя класса - V8X.ComConnector). Варианты:

  2. Внутрипроцессное (inproc)

  3. Должен быть зарегистрирован класс V8X.ComConnector той же разрядности, что и COM-клиент

  4. Если издание платформы COM-клиента совпадает с изданием платформы COM-сервера, то также требуется равенство сборки платформы COM-клиента и COM-сервера. 

  5. Он регистрируется при установке платформы с опцией «Внешнее соединение». В любой момент его можно зарегистрировать командой «Regsvr32 comcntr.dll» в каталоге исполняемых файлов платформы.

  6. COM-объект создается в памяти COM-клиента

  7. Затраты на создание примерно – 0.01(первое)/0.001(второе) cек

  8. Пример 
    КомСоединитель = Новый COMОбъект(“V83.ComConnector”);
    ВнешнееСоединение = КомСоединитель.Connect(СтрокаСоединения);

  9. Внепроцессное локальное (local)

  10. Должен быть зарегистрирован класс V8X.ComConnector любой разрядности и сборки платформы. Необходимо настроить через dcomcnfg.exe COM+ приложение с активацией «серверное приложение»/«Server apllication». Подробнее рассмотрено далее.

  11. COM-объект создается в памяти служебного хост-процесса (dllhost.exe) на компьютере COM-клиента

  12. Затраты на создание примерно – 0.06(первое)/0.03(второе) сек

  13. Пример 
    КомСоединитель = Новый COMОбъект(“V83.ComConnector”);
    ВнешнееСоединение = КомСоединитель.Connect(СтрокаСоединения);

  14. Внепроцессное нелокальное (DCOM)

  15. На нелокальном компьютере должен быть зарегистрирован класс V8X.ComConnector любой разрядности и сборки платформы. Необходимо настроить на нелокальном компьютере через dcomcnfg.exe COM+ приложение с активацией «Cерверное приложение»/«Server apllication». Подробнее рассмотрено далее.

  16. Необходимо настроить на нелокальном компьютере роль «Сервер приложений»/«Application server» и включить нелокальный доступ  COM+, выбрав опцию «Сетевой доступ к COM+»/”COM+ network access”. Подробнее рассмотрено далее.

  17. COM-объект создается в памяти служебного хост-процесса (dllhost.exe) на другом компьютере

  18. Затраты на создание примерно

  19. Экспериментальные данные

Задержка канала, мс

Длительность создания COM-объекта, мс

0

60

30

700

80

2000

170

4000


На графике видно, что длительность создания этого COM-объекта прямо пропорциональна задержке канала и коэффициент пропорциональности составляет  примерно 24. Можно предположить, что при создании этого COM-объекта происходит 24 вызова через канал.

  1. Пример
    КомСоединитель = Новый COMОбъект(“V83.ComConnector”, ИмяКомпьютера);
    ВнешнееСоединение = КомСоединитель.Connect(СтрокаСоединения);

  2. Выполнение метода Connect (создание внешнего соединения)

  3. Создание сеанса – 1 сек

  4. Инициализация сеанса – [0;?] сек

  5. ПередНачаломРаботыСистемы (только для Automation-сервера)

  6. ПриНачалеРаботыСистемы

  7. Инициализация параметров сеанса

  8. Подгрузка нужных метаданных

Затраты на COM-вызовы

Каждый раз, когда мы обращаемся во встроенном языке к свойству или методу COM-объекта (выполняем COM-вызов), происходит ряд дополнительных действий по сравнению с обращением к родному объекту встроенного языка. Если COM-сервер находится в другом локальном процессе, то при этом еще сначала выполняется перенос всех параметров из COM-клиента в COM-сервер и в конце выполняется обратный перенос параметров в COM-клиент. Для такого переноса информация естественно должна быть сериализована на стороне отправителя и  затем десериализована на стороне получателя, что в совокупности с некоторыми другими действиями получило название маршалинга и демаршалинга. В нелокальном режиме (DCOM) такой перенос будет еще тратить время на сетевые коммуникации и при первом обращении к новому COM-объекту на передачу его «скелета», и поэтому задержка канала будет играть решающую роль (Подробнее о COM вызовах, DCOM в википедии, Технический обзор DCOM,)

Соотношение затрат на вызов по типам расположения COM-сервера

  1. Минимальные для внутрипроцессного Com-сервера

  2. Средние для локального внепроцессного Com-сервера

  3. От средних до больших для нелокального внепроцессного Cоm-сервера в зависимости от качества канала связи

Минимизация количества COM-вызовов

  1. Создаем базовую внешнюю обработку с набором общих методов для приема вызовов от COM-клиента на стороне COM-сервера

  2. Теперь нам не нужно изменять конфигурацию базы COM-сервера, чтобы использовать там сложный функционал.

  3. В нашем продукте мы назвали ее «Сервисный процессор». На ее передачу и инициализацию уходит около 1 сек

  4. Проектируем взаимодействие с COM-сервером по принципу "минимум COM-вызовов”, т.е. готовим все нужное на стороне COM-клиента и передаем в качестве параметров одного большого вызова»

  5. Создаем встроенную обработку для выполнения такого вызова в COM-клиенте

  6. Передача агрегатных объектов

  7. Сериализуем все входные параметры на стороне COM-клиента

  8. Десериализуем все входные параметры на стороне COM-сервера

  9. Сериализуем все выходные параметры на стороне COM-сервера

  10. Десериализуем все выходные параметры на стороне COM-клиента

  11. В нашем продукте мы назвали ее «Выполнение сервиса инфобазы»

  12. Для многократных COM-вызовов предусматриваем регулируемую частоту

  13. Например, информационные вызовы могут выполняться с изменяемой частотой

Обратная связь

При использовании принципа «минимум COM-вызовов» значительную часть времени код будет выполняться в чужом контексте, что серьезно усиливает некоторые неудобства COM-вызовов:

  1. Нельзя прервать поток COM-Клиента и его соединение с сервером приложений 1С, пока не завершится вызов COM-сервера

  2. У COM-Клиента нет информации о прогрессе выполнения вызова в COM-сервере

Для борьбы с этими неудобствами можно организовать обратную связь от COM-сервера к COM-клиенту, передав COM-Серверу ссылку на общий модуль COM-клиента и периодически вызывая через нее COM-клиент. Нужно отметить, что есть ошибки платформы (https://partners.v8.1c.ru/forum/t/1382465/m/1382465 ), проявляющиеся при создании ссылок на один общий модуль более чем в одном COM-севере сеанса. Поэтому пока лучше очищать ссылки на общий модуль во всех удерживаемых COM-серверах перед помещением в новый. В обратных вызовах можно передавать:

  1. информацию о прогрессе выполнения

  2. накопленные сообщения пользователю (получать функцией ПолучитьСообщенияПользователю(Истина))

Схема принципа “минимум COM-вызовов”

Такая схема дружественна к большим задержкам каналов связи. Поэтому она во многом похожа на вызов веб-сервиса. А следовательно используя ее для COM взаимодействия, вы значительно снижаете затраты на возможные переходы между COM и веб-сервисом в обоих направлениях.

Отладка

При использовании принципа «минимум COM-вызовов» облегчить отладку выполнения кода на COM-сервере можно, сделав опциональное модальное окно подключения к базе в COM-клиенте. В этом окне должны быть возможности задания одноразовых параметров подключения, выполнения вспомогательных функций и просмотра информации о подключенном сеансе. Ниже в качестве примера показано такое окно из нашего продукта

Чтобы включить возможность отладки внешних соединений, в подкаталоге conf нужно создать файл comcntrcfg.xml с соответствующим содержимым. В окне подключения можно сделать кнопку/флажок для программного создания такого файла. Однако много версий платформы содержат ошибку, из-за которой предметы отладки внешних соединений не видны в отладчике даже с этим корректно настроенным файлом. На платформе 8.3 эти проблемы вроде бы решены.

Пример файла comcntrcfg.xml:
<config xmlns="http://v8.1c.ru/v8/comcntrcfg">
   <debugconfig debug="true" debuggerURL="tcp://localhost:1560"/>
</config>

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

В какой-то мере обойти проблему невидимости предмета отладки внешнего соединения и ряд других неудобств можно путем однократного выполнения кода  на толстом клиенте с заменой режима «Внешнее соединение» на «Automation-сервер» (приложение), т.е. используя COM класс V8X.Application и включенную видимость. Поэтому в окне подключения нужны параметры для выбора режима подключения.

После создания подключения на стороне COM-клиента обычно требуется подключение отладчика базы COM-сервера и установка там точки останова в нужном месте. Поэтому в окне подключения нужно расположить кнопку подключения отладчика/конфигуратора COM-сервера. Если COM-сервер запущен в режиме видимого приложения, то для подключения отладчика можно воспользоваться асинхронным вызовом исключения в нем. Из диалога с ошибкой в приложении COM-сервера через кнопку «Конфигуратор» можно будет открыть конфигуратор и в большинстве случаев сразу подключить отладчик. Если подключение отладчика таким способом недоступно, то оператору поможет отображение информации о сеансе (его номера) в базе COM-сервера. Также нужна кнопка открытия в открытом отладчике файла внешней обработки, которая будет выполняться в нем.

Управление COM классами и COM+ приложениями 1С

Управление COM классами

  1. Внешнее соединение (V8X.ComConnector)

  2. Регистрация: Regsvr32 comcntr.dll

  3. Отмена регистрации: Regsvr32 comcntr.dll /u

  4. Automation-сервер (V8X.Application)

  5. Регистрация - 1cv8.exe /regserver

  6. Отмена регистрации - 1cv8.exe /unregserver

Управление COM+ приложениями

Осуществляется через оснастку dcomcnfg.exe. Для регистрации 1С в качестве COM+ приложения необходимо открыть оснастку "dcomcnfg". В ней в ветке "Службы компонентов"-"Компьютеры"-"Мой компьютер"-"Приложения COM+"(COM+ Applications) необходимо добавить новое приложение (application). При добавлении можно указать любое имя. Далее необходимо указать пользователя, от имени которого будет работать COM+ приложение, на закладке Идентификация (Identity). Также нужно задать доступ к приложению для всех пользователей путем добавления, если отсутствует, роли с любым именем в ветке Роли (Roles), и добавления в ее ветку Пользователи (Users) пользователя Все (Everyone). После добавления приложения необходимо создать новую компоненту. Для этого в ветке "Компоненты" созданного приложения необходимо выбрать пункт меню "Создать"-"Компонент". При создании выбрать импорт уже зарегистрированных компонентов и найдите в списке (желательно 64-битную) компоненту 1С (V8x.COMConnector.1). 

Далее можно изменить тип активации (внутрипроцессный/внепроцессный) на закладке Активация/Activation.

В нашем продукте имеется инструмент «Управление COM классами 1С» для просмотра/регистрации/изменения всех COM классов и COM+ приложений 1С на указанном компьютере:

Настройка DCOM-сервера

Для Windows 2008 Server нужно добавить роль «Сервер приложений» (Application server). Для этого необходимо открыть панель управления компьютером, щелкнуть правой кнопкой мыши в ветки "Роли" и выбрать пункт меню "Добавить роль".

Появится око в котором необходимо выбрать роль "Сервер приложений"/"Application server". На этапе выбора ролей сервера приложений необходимо указать пункт "Сетевой доступ к COM+"/"COM+ network access". Если это не сделать, то при попытке создания COM-объекта вы будете получать ошибку "Ошибка при вызове конструктора (COMОбъект): The component or application containing the component has been disabled".

Проблемы

  1. Высокие затраты на подключение/инициализацию

  2. Удержание com-серверов – эффективное средство борьбы

  3. Временное хранилище. Производитель не рекомендует, но деваться больше некуда. http://infostart.ru/public/331683/

  4. Повторное использование возвращаемых значений. Очищаются каждые 20 мин

  5. Разные сборки платформы клиента и сервера при одинаковом издании платформы

  6. Для обхода для каждой отличной от COM-клиента сборки платформы назначаем и настраиваем DCOM сервер

  7. Отсутствие информации о типах вложенных в COM-объекты объектов 1С (вместо типа объекта 1С везде получаем тип «COMОбъект») и отсутствие контекстной подсказки по ним

  8. Для обхода применяем принцип «минимум COM-вызовов»

  9. При передаче исключения из COM-сервера оно принимает краткую форму из-за ошибки платформы

  10. Для обхода оборачиваем каждый вызов на стороне COM-сервера в попытку и в исключении перевызываем исключение с полным описанием ошибки

  11. При создании COM-объекта ошибка “Версия компоненты 'comcntr' (8.X.XX.XXX) отличается от версии корневого модуля 'core82' (8.X.YY.YYY)”

  12. Для обхода создаем COM+ приложение с внепроцессной активацией. Тогда COM-сервер будет создаваться в отдельном процессе и совпадения версий этих модулей не потребуется.

  13. Медленные каналы (большие задержки)

  14. Каждой подсети за отдельным медленным каналом назначаем и настраиваем свой DCOM сервер и при обращении к базам за этим каналом COM-серверы создаем на этом компьютере, минимизируя количество и объемы вызовов Com-клиент<->Com-сервер

  15. Кешируем (повторно используем) COM-серверы

  16. Невозможно разорвать соединение рабочего процесса, в котором ожидается завершение вызова COM-сервера

  17. Для обхода можно использовать создание COM-объектов в выделенных хост-процессах, настроив соответствующим образом COM+ приложение, и регистрировать идентификаторы этих процессов в привязке к сеансам COM-клиентов. Тогда при необходимости завершить серверное соединение такого сеанса можно сначала убить процесс COM-сервера, а потом и сам сеанс.

  18. При обращении к COM-объекту может возникать ошибка «Неизвестная ошибка». Возможные причины:

  19. Com-сервер перестал существовать. Возможные причины:

  20. Переполнение стека

  21. Невосстановимая ошибка

  22. Хост-процесс завершился

  23. Потеря связи с нелокальным COM-сервером

  24. Совпадение имен свойств и методов без параметров объекта создает неоднозначность обращения к ним через COM

  25. Например, если у справочника есть реквизит ПолноеНаименование, то из-за наличия метода ПолноеНаименование() обращение к реквизиту ПолноеНаименование через COM может привести к вызову метода ПолноеНаименование()

  26. Для обхода используем принцип “минимум COM-вызовов”

Com-технология VS веб-сервисы в локальной сети

Недостатки

  1. Рассмотренные выше сложности с взаимодействием разных сборок платформы 1C, требующие для своего решения сервисный механизм

  2. Высокие затраты на подключение/инициализацию, поэтому при отсутствии кеширования неэффективно для частых мелких вызовов

  3. Привязка к семейству операционных систем (платформе) Windows

Преимущества

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

  2. Широкая функциональность 

  3. Проще отладка

  4. Не требуется разворачивать и поддерживать веб-сервер

Захват клиентских лицензий

В большинстве случаев всем клиентским приложениям, частным случаем которого являются Automation-сервер и с оговорками является внешнее соединение, в одном сеансе ОС требуется всего лишь одна на всех лицензия. Однако если клиентскому приложению не удалось получить аппаратную лицензию (от локального HASP или сетевого HASP) и программную лицензию (платформы или базовой конфигурации), то предпринимается попытка получить отдельную лицензию с сервера 1С:Предприятия. Сервер 1С:Предприятия может выдать лицензию только, если в свойствах базы разрешена выдача лицензий сервером 1С:Предприятия. В таком случае каждое клиентское приложение и внешнее соединение может захватывать свою собственную лицензию.

Заключение

Если вы хотите подробнее узнать об описанных особенностях, вы можете бесплатно скачать конфигурацию и демонстрационную базу продукта, для чего необходимо оформить предварительный заказ на Инфостарте на продукт 2iS:Интеграция. Несмотря на наличие в конфигурации защищенного модуля, 99% программного кода конфигурации открыто, то есть Вы можете изучить реализацию описанных приемов.

Начать дискуссию