Как эффективно возвращать и передавать двоичные данные через веб-сервисы 1С

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

При разработке интеграционных решений на платформе 1С:Предприятие часто возникает задача передачи файлов, изображений или других бинарных объектов через SOAP веб-сервисы. Традиционный метод преобразования двоичных данных в строку через Base64 имеет существенный недостаток: объем передаваемого сообщения увеличивается примерно на 33%, что создает избыточную нагрузку на сеть и оперативную память сервера. В этой статье мы подробно разберем, как избежать «острочного» представления данных и использовать современные механизмы оптимизации, такие как MTOM.

Понимание механизма MTOM в 1С

Рассмотрим, почему обычное использование типа base64Binary в определении веб-сервиса часто приводит к неоптимальной передаче. По умолчанию данные действительно упаковываются в XML-пакет в виде текстовой строки. Однако, начиная с версии платформы 8.3.8, 1С поддерживает стандарт MTOM (Message Transmission Optimization Mechanism).

Суть MTOM заключается в том, что данные, описанные как base64Binary, не кодируются внутри XML. Вместо этого формируется multipart/related сообщение, где XML-конверт содержит лишь ссылку на двоичные данные, а сами данные передаются в «сыром» бинарном виде в отдельной части HTTP-запроса. Это позволяет значительно сэкономить ресурсы. Выясним, как правильно настроить этот механизм.

Настройка веб-сервиса на стороне сервера

Для начала проанализируем настройки самого объекта Web-сервис в конфигураторе. Чтобы платформа поняла, что параметр или возвращаемое значение является двоичными данными, необходимо выполнить следующие шаги:

  1. В дереве конфигурации выберем нужный веб-сервис и перейдем к его операциям.
  2. Для параметра или возвращаемого значения выберем тип из пространства имен XDTO.
  3. В качестве типа укажем base64Binary (пространство имен http://www.w3.org/2001/XMLSchema).

Важно: несмотря на название типа, содержащее слово «base64», использование MTOM на уровне транспорта «вынесет» эти данные из XML-текста. В программном коде 1С мы будем работать с объектом типа ДвоичныеДанные. Рассмотрим пример функции веб-сервиса:


Функция ПолучитьФайл(ИмяФайла)
    ПутьКФайлу = "C:\Files\" + ИмяФайла;
    ФайлНаДиске = Новый Файл(ПутьКФайлу);
    
    Если ФайлНаДиске.Существует() Тогда
        Возврат Новый ДвоичныеДанные(ПутьКФайлу);
    Иначе
        Возврат Неопределено;
    КонецЕсли;
КонецФункции

Активация MTOM на стороне клиента

Просто настроить сервер недостаточно. Разберем ситуацию: если клиент (другая база 1С или внешняя система) не заявит о поддержке MTOM, сервер 1С автоматически «откатится» к стандартной передаче в Base64 для обеспечения совместимости. Чтобы этого не произошло, при создании прокси веб-сервиса в 1С нужно явно включить соответствующий флаг.

Посмотрим на пример кода инициализации соединения:


// Определяем местоположение WSDL
Определения = Новый ОпределенияWebСервиса(URL_WSDL, Логин, Пароль);

// Включаем поддержку MTOM в параметрах
ИспользоватьMTOM = Истина;

// Создаем прокси с явным указанием использования оптимизации
Прокси = Новый WSПрокси(Определения, "http://www.my-service.ru", "MyService", "MyServiceSoap", , , ИспользоватьMTOM);

// Теперь при вызове метода данные будут передаваться эффективно
Результат = Прокси.ПолучитьФайл("report.pdf");

Если вы используете динамическое создание WSПрокси без предварительного создания объекта ОпределенияWebСервиса, убедитесь, что версия платформы и настройки позволяют корректно инициализировать свойство ИспользоватьMTOM.

Использование типа ValueStorage (ХранилищеЗначения)

В некоторых обсуждениях предлагается использовать тип ValueStorage (из пространства имен http://v8.1c.ru/8.1/data/core). Рассмотрим этот вариант подробнее. Этот тип удобен, когда обмен происходит исключительно между двумя базами 1С. Платформа берет на себя сериализацию объекта, включая сжатие и информацию о типе.

Однако, если ваш веб-сервис предназначен для интеграции с внешними системами (написанными на Java, C# или Python), использование ValueStorage крайне не рекомендуется. Внешняя система не сможет легко десериализовать внутренний формат 1С. В таких случаях стандартом де-факто остается base64Binary с включенным MTOM.

Проблема больших файлов: Чанкинг (передача по частям)

Даже с использованием MTOM передача файлов размером в несколько сотен мегабайт может вызвать проблемы. Оперативная память процесса rphost может быть переполнена, так как объект ДвоичныеДанные должен быть полностью загружен в память перед отправкой.

Проанализируем стратегию «разрезания» файла на части. Мы можем реализовать логику, при которой клиент запрашивает файл частями (чанками). Для этого создадим метод веб-сервиса, принимающий смещение и размер порции:


Функция ПолучитьЧастьФайла(ИдентификаторФайла, Смещение, РазмерПорции)
    // Логика чтения части файла с диска через ЧтениеДанных или ФайловыйПоток
    ФайлСтрим = Новый ФайловыйПоток("C:\Temp\" + ИдентификаторФайла, РежимОткрытияФайла.Открыть, ДоступКФайлу.Чтение);
    ФайлСтрим.УстановитьПозицию(Смещение, РежимПеремещенияВФайле.Начало);
    
    Буфер = Новый БуферДвоичныхДанных(РазмерПорции);
    Прочитано = ФайлСтрим.Прочитать(Буфер, 0, РазмерПорции);
    
    ФайлСтрим.Закрыть();
    
    // Возвращаем только прочитанный кусок
    Возврат Буфер.ПолучитьДвоичныеДанные();
КонецФункции

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

Альтернатива: Переход на HTTP-сервисы

Выясним, стоит ли вообще использовать SOAP для передачи тяжелых бинарных данных. Современная практика разработки в 1С склоняется к использованию HTTP-сервисов. В отличие от веб-сервисов (SOAP), HTTP-сервисы позволяют работать с телом HTTP-ответа напрямую.

Преимущества HTTP-сервисов для бинарных данных:

  1. Отсутствие накладных расходов на XML-конверт.
  2. Возможность установки произвольного Content-Type (например, application/octet-stream или image/png).
  3. Простая потоковая передача.

Пример реализации передачи файла через HTTP-сервис:


Функция ПолучитьФайл(Запрос)
    Ответ = Новый HTTPСервисОтвет(200);
    ПутьКФайлу = "C:\Data\image.jpg";
    
    ДвоичныеДанные = Новый ДвоичныеДанные(ПутьКФайлу);
    Ответ.УстановитьТелоИзДвоичныхДанных(ДвоичныеДанные);
    Ответ.Заголовки.Вставить("Content-Type", "image/jpeg");
    
    Возврат Ответ;
КонецФункции

Настройка веб-серверов (IIS и Apache)

Часто ошибки при передаче двоичных данных возникают не в 1С, а на уровне веб-сервера, который проксирует запросы. Рассмотрим основные настройки:

Для IIS: необходимо проверить лимит на размер контента. По умолчанию он может быть ограничен 30 МБ. В файле web.config следует настроить параметр:

maxAllowedContentLength в секции requestLimits.

Для Apache: обратите внимание на директиву LimitRequestBody. Если она установлена в небольшое значение, сервер будет обрывать соединение при попытке передать большой бинарный поток.

Подводя итог, можно сказать: если вы ограничены рамками SOAP, используйте base64Binary в связке с ИспользоватьMTOM = Истина. Если же архитектура позволяет выбирать — HTTP-сервисы будут более производительным и современным решением для работы с двоичными данными.

← На главную