При разработке интеграционных механизмов в управляемом приложении 1С программисты часто сталкиваются с задачей сохранения установленного внешнего COM-соединения (например, через V83.COMConnector) между несколькими несвязанными серверными вызовами. Повторная инициализация соединения при каждом нажатии кнопки или обработке порции данных требует значительных накладных расходов по времени.
Однако при попытке сохранить полученную ссылку на COM-объект стандартными средствами разработчики сталкиваются с ошибками платформы. Выясним причину такого поведения и разберем работающие способы решения данной задачи, а также архитектурные ограничения платформы 1С:Предприятие.
Проанализируем ситуацию: платформа 1С разделяет контекст выполнения на клиентский и серверный уровни. Это накладывает строгие ограничения на типы данных:
COMОбъект не может использоваться в качестве типа данных формы, поскольку данные формы должны сериализоваться для передачи между сервером и клиентом. При попытке присвоения возникает исключение: «Тип "COMОбъект" не может использоваться в данных формы».&НаКлиенте Перем V8; и передать ее параметром в серверную процедуру вызывает ошибку сериализации XDTO: «Ошибка передачи данных между клиентом и сервером. Значение недопустимого типа».ПоместитьВоВременноеХранилище(COMОбъект, УникальныйИдентификатор) завершается ошибкой, так как платформа требует сериализуемый объект верхнего уровня.Разберем по шагам наиболее практичный способ передачи указателя между серверными вызовами одной сессии формы без изменения конфигурации. Платформа 1С позволяет поместить несериализуемый объект во временное хранилище, если обернуть его в коллекцию — например, в объект Структура или Соответствие.
Посмотрим на пример инициализации и сохранения адреса хранилища в строковый реквизит объекта или формы:
&НаСервере
Процедура ИнициализироватьСоединениеНаСервере()
COMКоннектор = Новый COMОбъект("V83.COMConnector");
УстановленноеСоединение = COMКоннектор.Connect(СтрокаПодключения);
// Оборачиваем COM-объект в структуру
Контейнер = Новый Структура("COMСоединение", УстановленноеСоединение);
// Сохраняем адрес хранилища в строковый реквизит формы
АдресХранилищаCOM = ПоместитьВоВременноеХранилище(Контейнер, УникальныйИдентификатор);
КонецПроцедуры
Рассмотрим, как получить ранее сохраненное соединение в последующих несвязанных серверных процедурах:
&НаСервере
Процедура ВыполнитьОперациюНаСервере()
Если Не ЗначениеЗаполнено(АдресХранилищаCOM) Тогда
Возврат;
КонецЕсли;
// Извлекаем контейнер из временного хранилища
Контейнер = ПолучитьИзВременногоХранилища(АдресХранилищаCOM);
Если Контейнер <> Неопределено И Контейнер.Свойство("COMСоединение") Тогда
V8 = Контейнер.COMСоединение;
// Выполняем действия в подключенной базе
РезультатЗапроса = V8.NewObject("Запрос");
// ... работа с базой
КонецЕсли;
КонецПроцедуры
Другой способ кэширования объекта на сервере — использование функционала платформы по кэшированию функций. Для этого в конфигурации создается общий модуль с установленным свойством Повторное использование возвращаемых значений в значение На время сеанса.
Разберем реализацию функции внутри такого модуля:
// В общем модуле с повторным использованием "На время сеанса"
Функция ПолучитьКэшированноеCOMСоединение(СтрокаПодключения) Экспорт
COMКоннектор = Новый COMОбъект("V83.COMConnector");
Соединение = COMКоннектор.Connect(СтрокаПодключения);
// Кэшируем внутри структуры или соответствия
Результат = Новый Структура("Подключение", Соединение);
Возврат Результат;
КонецФункции
Рассмотрим особенности этого метода:
ОсвежитьПовторноИспользуемыеЗначения().Используя сохранение COM-соединений между вызовами, необходимо учитывать технические особенности архитектуры 1С:
rphost. Если кластер серверов балансирует нагрузку и перенаправит следующий серверный вызов клиента на другой рабочий процесс или другой сервер, попытка прочитать COM-указатель из временного хранилища приведет к ошибке.V83.COMConnector удерживает клиентскую лицензию в подключаемой базе на все время своего существования. Длительное хранение объекта в памяти расходует пул доступных лицензий.V8 = Неопределено;.Если требуется надежная архитектура обмена данными между базами 1С, рекомендуется использовать современные платформенные механизмы:
ФоновыеЗадания.Выполнить(). Вся работа с COM-коннектором от подключения до закрытия выполняется в рамках одного процесса без разрыва контекста.HTTPСервисы. Такие запросы выполняются по стандарту без сохранения состояния (stateless), одинаково работают на Windows и Linux и не зависят от процессов кластера.