При разработке интеграционных решений на платформе 1С:Предприятие часто возникает задача передачи файлов, изображений или других бинарных объектов через SOAP веб-сервисы. Традиционный метод преобразования двоичных данных в строку через Base64 имеет существенный недостаток: объем передаваемого сообщения увеличивается примерно на 33%, что создает избыточную нагрузку на сеть и оперативную память сервера. В этой статье мы подробно разберем, как избежать «острочного» представления данных и использовать современные механизмы оптимизации, такие как MTOM.
Рассмотрим, почему обычное использование типа base64Binary в определении веб-сервиса часто приводит к неоптимальной передаче. По умолчанию данные действительно упаковываются в XML-пакет в виде текстовой строки. Однако, начиная с версии платформы 8.3.8, 1С поддерживает стандарт MTOM (Message Transmission Optimization Mechanism).
Суть MTOM заключается в том, что данные, описанные как base64Binary, не кодируются внутри XML. Вместо этого формируется multipart/related сообщение, где XML-конверт содержит лишь ссылку на двоичные данные, а сами данные передаются в «сыром» бинарном виде в отдельной части HTTP-запроса. Это позволяет значительно сэкономить ресурсы. Выясним, как правильно настроить этот механизм.
Для начала проанализируем настройки самого объекта Web-сервис в конфигураторе. Чтобы платформа поняла, что параметр или возвращаемое значение является двоичными данными, необходимо выполнить следующие шаги:
base64Binary (пространство имен http://www.w3.org/2001/XMLSchema).Важно: несмотря на название типа, содержащее слово «base64», использование MTOM на уровне транспорта «вынесет» эти данные из XML-текста. В программном коде 1С мы будем работать с объектом типа ДвоичныеДанные. Рассмотрим пример функции веб-сервиса:
Функция ПолучитьФайл(ИмяФайла)
ПутьКФайлу = "C:\Files\" + ИмяФайла;
ФайлНаДиске = Новый Файл(ПутьКФайлу);
Если ФайлНаДиске.Существует() Тогда
Возврат Новый ДвоичныеДанные(ПутьКФайлу);
Иначе
Возврат Неопределено;
КонецЕсли;
КонецФункции
Просто настроить сервер недостаточно. Разберем ситуацию: если клиент (другая база 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 (из пространства имен http://v8.1c.ru/8.1/data/core). Рассмотрим этот вариант подробнее. Этот тип удобен, когда обмен происходит исключительно между двумя базами 1С. Платформа берет на себя сериализацию объекта, включая сжатие и информацию о типе.
Однако, если ваш веб-сервис предназначен для интеграции с внешними системами (написанными на Java, C# или Python), использование ValueStorage крайне не рекомендуется. Внешняя система не сможет легко десериализовать внутренний формат 1С. В таких случаях стандартом де-факто остается base64Binary с включенным MTOM.
Даже с использованием MTOM передача файлов размером в несколько сотен мегабайт может вызвать проблемы. Оперативная память процесса rphost может быть переполнена, так как объект ДвоичныеДанные должен быть полностью загружен в память перед отправкой.
Проанализируем стратегию «разрезания» файла на части. Мы можем реализовать логику, при которой клиент запрашивает файл частями (чанками). Для этого создадим метод веб-сервиса, принимающий смещение и размер порции:
Функция ПолучитьЧастьФайла(ИдентификаторФайла, Смещение, РазмерПорции)
// Логика чтения части файла с диска через ЧтениеДанных или ФайловыйПоток
ФайлСтрим = Новый ФайловыйПоток("C:\Temp\" + ИдентификаторФайла, РежимОткрытияФайла.Открыть, ДоступКФайлу.Чтение);
ФайлСтрим.УстановитьПозицию(Смещение, РежимПеремещенияВФайле.Начало);
Буфер = Новый БуферДвоичныхДанных(РазмерПорции);
Прочитано = ФайлСтрим.Прочитать(Буфер, 0, РазмерПорции);
ФайлСтрим.Закрыть();
// Возвращаем только прочитанный кусок
Возврат Буфер.ПолучитьДвоичныеДанные();
КонецФункции
Такой подход позволяет передавать гигабайтные файлы, не создавая пиковых нагрузок на сервер.
Выясним, стоит ли вообще использовать SOAP для передачи тяжелых бинарных данных. Современная практика разработки в 1С склоняется к использованию HTTP-сервисов. В отличие от веб-сервисов (SOAP), HTTP-сервисы позволяют работать с телом HTTP-ответа напрямую.
Преимущества HTTP-сервисов для бинарных данных:
Content-Type (например, application/octet-stream или image/png).Пример реализации передачи файла через HTTP-сервис:
Функция ПолучитьФайл(Запрос)
Ответ = Новый HTTPСервисОтвет(200);
ПутьКФайлу = "C:\Data\image.jpg";
ДвоичныеДанные = Новый ДвоичныеДанные(ПутьКФайлу);
Ответ.УстановитьТелоИзДвоичныхДанных(ДвоичныеДанные);
Ответ.Заголовки.Вставить("Content-Type", "image/jpeg");
Возврат Ответ;
КонецФункции
Часто ошибки при передаче двоичных данных возникают не в 1С, а на уровне веб-сервера, который проксирует запросы. Рассмотрим основные настройки:
Для IIS: необходимо проверить лимит на размер контента. По умолчанию он может быть ограничен 30 МБ. В файле web.config следует настроить параметр:
maxAllowedContentLength в секции requestLimits.
Для Apache: обратите внимание на директиву LimitRequestBody. Если она установлена в небольшое значение, сервер будет обрывать соединение при попытке передать большой бинарный поток.
Подводя итог, можно сказать: если вы ограничены рамками SOAP, используйте base64Binary в связке с ИспользоватьMTOM = Истина. Если же архитектура позволяет выбирать — HTTP-сервисы будут более производительным и современным решением для работы с двоичными данными.