Как передать большой файл с клиента на сервер 1С без зависания интерфейса

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

При разработке под управляемый интерфейс 1С:Предприятия часто возникает задача загрузки объемных файлов (архивов, дампов баз, медиафайлов размером от сотен мегабайт до нескольких гигабайт) с клиентского рабочего места на сервер. Разработчики нередко рассчитывают на штатные асинхронные методы платформы, однако на практике сталкиваются с полным зависанием интерфейса формы на время передачи данных.

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

Почему штатные асинхронные методы блокируют интерфейс

Проанализируем работу штатных механизмов помещения файлов, таких как ПоместитьФайлНаСерверАсинх(), ПоместитьФайлыНаСерверАсинх() или устаревший метод НачатьПомещениеФайла():

  1. Однопоточный цикл событий клиента (Event Loop). Асинхронность в клиентском приложении 1С построена по модели единого потока событий. Конструкции Асинх и Ждать освобождают стек вызовов, но не выделяют отдельный системный поток операционной системы для сетевого обмена. Вся передача данных происходит внутри процесса клиента.
  2. Один логический транспортный канал сеанса. Тонкий клиент держит единое соединение с сервером 1С. Пока по этому каналу непрерывно передается массивный поток двоичных данных, любые другие серверные вызовы из этого сеанса встают в очередь ожидания. В результате интерфейс перестает реагировать на действия пользователя, требующие обращения к серверу.
  3. Потребление оперативной памяти. При попытке прочитать файл объемом 1 ГБ целиком в объект ДвоичныеДанные или поместить его во временное хранилище весь объем данных выгружается в оперативную память клиентского процесса и серверного процесса rphost. Для 32-разрядных клиентов это практически гарантированно приводит к критической ошибке нехватки памяти.

Таким образом, организовать полностью независимую фоновую передачу файлов объемом около 1 ГБ исключительно через стандартное помещение во временное хранилище в текущем сеансе невозможно. Рассмотрим проверенные архитектурные альтернативы.

Решение 1. Прямая загрузка через сетевую папку и фоновое задание

Самый простой и надежный подход для работы внутри локальной корпоративной сети — исключить передачу тяжелых данных через внутренний транспорт 1С.

Разберем алгоритм по шагам:

  1. На сервере или выделенном файловом хранилище настраивается сетевой ресурс (папка с общим доступом SMB/NFS).
  2. Клиентское приложение 1С с помощью метода КопироватьФайлАсинх() или через внешний командный скрипт копирует файл в сетевой каталог, назначая ему уникальное временное имя (например, с использованием Строка(Новый УникальныйИдентификатор())).
  3. После успешного копирования клиент вызывает серверную процедуру и передает только путь к файлу.
  4. Сервер запускает длительную обработку переданного файла в фоновом задании с помощью менеджера ФоновыеЗадания.

Посмотрим на пример вызова фонового задания на сервере:


&НаСервере
Процедура ЗапуститьОбработкуФайлаНаСервере(ПутьКФайлуВСети)
    ПараметрыЗадания = Новый Массив;
    ПараметрыЗадания.Добавить(ПутьКФайлуВСети);
    
    ФоновыеЗадания.Выполнить(
        "ИнтеграцияСервер.ОбработатьЗагруженныйФайл", 
        ПараметрыЗадания, 
        Строка(Новый УникальныйИдентификатор()), 
        "Обработка большого файла"
    );
КонецПроцедуры

Решение 2. Использование HTTP-сервисов 1С и сторонних утилит

Если прямого сетевого доступа к файловой системе сервера у пользователей нет (например, работа идет через интернет или распределенные филиалы), передачу можно вынести в отдельный процесс операционной системы, настроив прием данных через HTTP-сервис 1С.

Схема работы выглядит следующим образом:

  1. В конфигурации создается HTTP-сервис, метод которого принимает поток двоичных данных и сразу записывает его на диск сервера через ФайловыйПоток (чтобы не переполнять оперативную память процесса rphost).
  2. На клиенте по нажатию кнопки запускается сторонняя консольная утилита (например, curl или собственный скрипт), которая отправляет файл методом POST или PUT отдельным независимым системным процессом.
  3. Для запуска процесса из 1С без блокировки интерфейса используем метод ЗапуститьПриложениеАсинх().

Посмотрим на пример формирования команды для фоновой отправки:


&НаКлиенте
Асинх Процедура ОтправитьФайлВФоне(ПутьКФайлу, ТокенАвторизации)
    АдресСервиса = "https://1c.company.ru/base/hs/files/upload";
    КомандаЗапуска = СтрШаблон(
        "curl -X POST --data-binary ""@%1"" -H ""Authorization: Bearer %2"" ""%3""",
        ПутьКФайлу,
        ТокенАвторизации,
        АдресСервиса
    );
    
    // Запуск процесса без ожидания завершения (интерфейс 1С свободен)
    Оповещение = Новый ОписаниеОповещения("ПослеЗапускаПередачи", ЭтотОбъект);
    ЗапуститьПриложение(КомандаЗапуска, , Ложь, 0);
КонецПроцедуры

Решение 3. Прямая загрузка в объектное хранилище (S3 / MinIO)

Для высоконагруженных систем стандартом является архитектура прямой загрузки (Direct Upload), минуя кластер серверов 1С:

  1. Клиент 1С обращается к серверу с кратким запросом на получение временной подписанной ссылки для загрузки (Presigned URL) в S3-совместимое хранилище (MinIO, Ceph, облачный провайдер).
  2. Сервер 1С генерирует ссылку с ограниченным временем жизни и возвращает ее клиенту.
  3. Загрузка файла выполняется напрямую в S3 через фоновый процесс, внешнюю компоненту или встроенный компонент браузера (если используется веб-клиент).
  4. После завершения загрузки S3-хранилище через Webhook или регламентное задание 1С уведомляет базу о готовности файла к обработке.

Решение 4. Применение внешних компонент (Native API)

Если требуется полностью бесшовный интерфейс внутри тонкого клиента без сторонних консольных окон, оптимальным решением выступает разработка или подключение внешней компоненты, созданной по технологии Native API (на C++, Rust или C#):

  1. Внешняя компонента загружается в сеанс клиента и при вызове метода создает отдельный поток ОС.
  2. Поток осуществляет сетевую передачу файла на целевой сервер (по протоколам HTTP, FTP, TCP).
  3. Основной интерфейс 1С остается полностью отзывчивым.
  4. По окончании передачи компонента генерирует внешнее событие с помощью штатного механизма, которое перехватывается в 1С через процедуру ОбработкаВнешнегоСобытия формы или модуля управляемого приложения.

Как оповестить пользователя о завершении обработки

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


// Серверный код фонового задания после обработки файла
Сообщение = СистемаВзаимодействия.СоздатьСообщение();
Сообщение.Получатели.Добавить(ПользовательИнициатор);
Сообщение.Текст = "Файл успешно загружен и обработан сервером.";
Сообщение.Записать();

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

← На главную