Как ускорить создание динамической фабрики XDTO и сохранить её отдельно от метаданных в 1С

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При интеграции с внешними сервисами через веб-сервисы и API (например, ВетИС «Меркурий») разработчики часто сталкиваются с ситуацией, когда статическую WS-ссылку невозможно добавить в дерево метаданных конфигурации. Конфигуратор выдает критическую ошибку: «набор схем не может содержать схемы с одинаковыми целевыми пространствами имен». Это происходит из-за того, что WSDL-описание сервиса или каскадно импортируемые им XSD-файлы содержат повторяющиеся пространства имен (targetNamespace).

В качестве обходного пути фабрику XDTO и определения сервиса создают динамически программным кодом. Однако при каждом обращении к удаленному URL (http://...) платформа выполняет сетевые запросы, скачивая WSDL и все зависимые XSD-схемы заново. Это приводит к задержкам от 3 до 6 секунд на каждый запрос. Попытка сохранить готовую фабрику в ХранилищеЗначения или преобразовать её через ЗначениеВСтрокуВНутр() завершается ошибкой, так как объекты ФабрикаXDTO, WSОпределения и WSПрокси в платформе 1С являются несериализуемыми.

Разберем подробнее, как обойти данные ограничения и сократить время формирования фабрики XDTO до долей секунды.

Способ 1. Хранение XSD-схем в макетах конфигурации

Проанализируем причину долгой инициализации: основное время уходит на сетевые HTTP/HTTPS-запросы для загрузки схем с удаленного сервера. Если мы исключим сеть и предоставим платформе схемы локально, фабрика будет инициализироваться практически мгновенно.

Разберем по шагам реализацию этого механизма:

  1. Скачаем необходимые XSD-схемы сервиса на локальный компьютер.
  2. Добавим их в конфигурацию как макеты (в общий макет или макет конкретного объекта/обработки). В качестве типа макета выберем Двоичные данные или Текстовый документ.
  3. При выполнении обмена выгрузим файл схемы во временный каталог на сервере и передадим путь в функцию СоздатьФабрикуXDTO().

Посмотрим на пример программной реализации:


// 1. Формируем путь во временном каталоге
ИмяКаталога = ПолучитьКаталогВременныхФайлов() + "XSD_Schema_" + Строка(Новый УникальныйИдентификатор()) + "\";
СоздатьКаталог(ИмяКаталога);

ПутьКФайлуСхемы = ИмяКаталога + "SchemaXSD_Exchange.xsd";

// 2. Получаем макет и сохраняем его на диск
МакетСхемы = Обработки.ИнтеграцияСМеркурием.ПолучитьМакет("СхемаXSDОбмена");
МакетСхемы.Записать(ПутьКФайлуСхемы);

// 3. Создаем фабрику XDTO из локального файла
МояФабрикаXDTO = СоздатьФабрикуXDTO(ПутьКФайлуСхемы);

// 4. После завершения работы каталог можно очистить
УдалитьФайлы(ИмяКаталога);

Такой подход полностью устраняет зависимость от стабильности удаленного сервера при инициализации схемы и ускоряет процесс в разы.

Способ 2. Кэширование фабрики в оперативной памяти сеанса

Хотя объект ФабрикаXDTO нельзя записать в базу данных через ХранилищеЗначения, его можно хранить в оперативной памяти сервера 1С на протяжении всего сеанса пользователя.

Для этого воспользуемся механизмом общих модулей с повторным использованием возвращаемых значений:

  1. Создадим общий серверный модуль, например, ИнтеграцияПовтИсп.
  2. В свойствах модуля установим флаг Сервер и для свойства Повторное использование возвращаемых значений укажем На время сеанса.
  3. Создадим экспортную функцию, возвращающую фабрику XDTO.

Посмотрим на пример кода в общем модуле:


Функция ПолучитьФабрикуXDTOСервиса() Экспорт
    
    // Получаем макет с двоичными данными схемы
    ДвоичныеДанныеСхемы = ОбщиеМакеты.СхемаМеркурийXSD.Получить();
    
    ПутьКФайлу = ПолучитьИмяВременногоФайла("xsd");
    ДвоичныеДанныеСхемы.Записать(ПутьКФайлу);
    
    Фабрика = СоздатьФабрикуXDTO(ПутьКФайлу);
    
    УдалитьФайлы(ПутьКФайлу);
    
    Возврат Фабрика;
    
КонецФункции

При первом обращении к функции ИнтеграцияПовтИсп.ПолучитьФабрикуXDTOСервиса() платформа создаст фабрику и сохранит ее в памяти. При всех последующих вызовах внутри текущего сеанса 1С готовый объект будет возвращаться мгновенно (за 0 миллисекунд) без повторного чтения файлов и парсинга схем.

Способ 3. Объединение дублирующихся схем для импорта в WS-ссылки

Если для архитектуры решения принципиально иметь строго типизированную WS-ссылку непосредственно в дереве метаданных конфигурации, можно устранить первопричину ошибки импорта:

  1. Скачаем WSDL-файл и все зависимые XSD-схемы на локальный диск.
  2. Откроем схемы в текстовом редакторе или специализированной среде разработки XML и найдем блоки с идентичными значениями атрибута targetNamespace.
  3. Объединим объявления типов и элементов с одинаковыми пространствами имен в один общий XSD-файл, удалив дублирующиеся заголовки <xs:schema>.
  4. Скорректируем пути в атрибутах schemaLocation тегов import и include в WSDL-файле, указав локальные объединенные файлы схем.
  5. Импортируем отредактированный WSDL в ветку метаданных WS-ссылки Конфигуратора 1С.

Способ 4. Прямая отправка через HTTPСоединение

Если интеграция включает частую отправку стандартных запросов, можно полностью отказаться от тяжеловесных объектов WSПрокси и ФабрикаXDTO:

  1. Формировать тело SOAP-запроса вручную с помощью объектов ЗаписьXML или ДокументDOM.
  2. Отправлять XML-конверт через HTTPСоединение методом POST с установкой необходимых HTTP-заголовков (SOAPAction, Content-Type: text/xml; charset=utf-8).
  3. Ответ сервиса разбирать напрямую через объект ЧтениеXML.

Это исключает любые накладные расходы платформы на инициализацию и валидацию структуры XDTO при каждом запуске операций обмена.

← На главную