1с большой файл обмена

Обновлено: 05.07.2024

Стандартный метод обмена данными между клиентом и сервером - временное хранилище. На одной стороне мы выполняем вызов "ПоместитьВоВременноеХранилище", получаем адрес, передаем его на другую сторону, там выполняем "ПолучитьИзВременногоХранилища". Есть пара неприятных нюансов.

  • За один вызов невозможно поместить во временное хранилище больше 4 Гб данных.
  • В процессе помещения данных в ВХ (здесь и далее временное хранилище) активно используются временные файлы. Точных данных нет, но в процессе помещения в темпах занимается временными файлами четырёхкратный объём помещаемого файла. Помещаете 4 Гб - потребуется ещё 16 Гб на разделе, где размещен temp. С нескромными аппетитами можно бы смириться (всё таки дисковое пространство - не самый дорогой ресурс в наши дни), если говорить об исключительности ситуаций, когда требуется обмен большими объемами данных. Если же эта операция выполняется регулярно, большим количеством пользователей, то велик шанс, что одновременно потребуется место для 10-100-Х (подставьте любое большое число загрузок, которое вам нравится) одновременных закачек, которые могут израсходовать всё свободное место на диске.
  • Из второй проблемы вытекает ещё и третья. Скорость записи на жесткий диск (в том числе во временные файлы) не бесконечна, хоть и ожидается выше скорости обмена по сети. А значит, запись пятикратного объема данных (сами данные и четырёхкратный темп для них) займёт пропорционально в 5 раз больше времени, чем если бы данные записывались ровно 1 раз.

Пути решения проблемы.

Как это устроено. Общее описание ландшафта.

Адреса методов "ПередачаДанных"

2. Ответ на запрос содержит токен. В дальнейшем этот токен используется для анонимного доступа к сервисам "передачи данных". Токен может быть использован только для той операции, которая была запрошена в запросе. Нельзя запросить скачивание файла А, а вместо этого загрузить на сервер файл Б. Токен действителен в течение 10 минут после регистрации запроса. После каждого обращения по токену время его жизни продляется на 10 минут.

Пример реализации загрузки данных на сервер в тонком клиенте

далее следует неудобная для листинга цепочка якобы асинхронных вызовов, получение размера файла итд. Этот этап пропустим, переходим сразу к загрузке.

Пример реализации скачивания данных с сервера в тонком клиенте

  • как то находим наш идентификатор
  • формируем запрос на скачивание, как в предыдущем пункте
  • формируем полный URL загружаемого файла
  • делаем гиперссылку с этим URL на форме

На самом деле немного сложнее, но об этом в последнем разделе

Пример реализации загрузки данных на сервер в веб-клиенте


А вот java script позволяет. Поэтому было принято решение для веб клиента экспроприировать диалог выбора файла прямо из браузера со всеми стилями и использовать его в своих корыстных целях. HTML форма диалога выбора файла позволяет перетаскивать файл(ы) drag'drop-ом, сразу несколько (хотя это и запрещено в примере), показывает полосу прогресса (чего в 8.3.15 так и не сделали), ну и конечно же работает с библиотекой "Передача данных". Более подробно смотрите внешнюю обработку в приложениях к статье.

Концепт скачивания данных с сервера в веб-клиенте

Проанализировав активность на сервере (дисковую в первую очередь) было выяснено, что файл после запроса начинает бродить по темпам. Сначала его копирует сервер предприятия, потом веб-сервер, потом (в моём случае на внешний мир смотрел ещё 1 слой из nginx в роли reverse proxy) ещё раз это делает nginx. И вот, пока идёт копирование файла во временные, колёсико крутится и мы ждём. Если файл не успевает скопироваться за настроенное время ожидания - привет 504 (Gateway timeout).

На просторах интернета было найдено решение по рекомендации "лучших собаководов". Оно достаточно зависит от используемого веб-сервера.

Аналогичный инструмент существует для Apache (если вам не нужен reverse proxy) -

PS: Не судите строго за не совсем ИС тематику публикации. Очень огорчает распространенное мнение, что 1С - это медленно, местячковый продукт для своих целей и своего рынка.

PPS: файл внешней обработки "выдирался" из конфигурации, возможно содержит ошибки. Тестирование проводилось на конфигурации Менеджер сервиса 1.0.83.10. Если будут проблемы, с удовольствием помогу разобраться в комментариях и/или обновлениях статьи.

Автор статьи - Виктор Сахнов (Asmody)

Сразу замечу, что все нижеследующее относится к релизу платформы 8.0.7.36 и выше.

Шаг 1. Создание плана обмена

Создаем в конфигурации план обмена. Называем его, например "РаспределеннаяБаза". Обязательно в
свойствах плана обмена ставим флажок "Распределенная информационная база".

На закладке "Прочее" по кнопке "Состав" определяем, какие объекты будут включаться в обмен. По
умолчанию можно включить все объекты ("Действия"-"Включить все"). Важным моментом является параметр
"Авторегистрация". В общем случае ее нужно разрешить для всех объектов.

Замечание: при добавлении новых объектов в конфигурацию, они не включаются в план обмена. Т.е. после
добавления объекта его необходимо добавить в состав плана обмена.

Если Вы хотите, чтобы некоторые объекты не участвовали в обмене, просто исключаете их из состава
плана обмена. Но тогда контроль ссылочной целостности остается целиком на вашей совести. Если, к
примеру, некий документ не включен в план обмена, а регистр, по которому он делает движения включен,
то в базе-приемнике вполне реально получить движения по регистру без документа-регистратора, что
согласитесь, не есть хорошо.

В принципе, этих действий достаточно, чтобы РБД заработала в "ручном" режиме. Для этого запускаем
Предприятие, открываем наш план обмена через меню "Операции". В плане обмена всегда присутствует
предопределенный узел "с точкой". Это описание текущего узла. Его нужно открыть и заполнить. В нашем
случае будут доступны поля "Код" и "Наименование". Присвоим нашему узлу код "AA" и назовем
"Центральная". Добавим в план обмена один узел. Присвоим ему код "ВВ" и назовем "Периферийная".

Теперь мы можем создать образ периферийной базы. Делается это нажатием кнопки "Создать начальный
образ". В списке узлов должна быть выбрана периферийная база. Образ базы создается в виде готовой ИБ
в каталоге или на сервере 1С:Предприятия. (в отличие от 7.7, где образ ИБ создавался как файл
выгрузки). Далее созданную базу можно перенести в нужное место, просто скопировав файлик 1CV8.1CD
(для файлового варианта), либо через Конфигуратор через выгрузку-загрузку данных.

Если Вы откроете план обмена в периферийной ИБ, то Вы увидите, что узлом "с точкой", т.е. текущим
узлом стал узел "Периферийная", а иконка у узла "Центральная" стала красного цвета, т.е. узел
"Центральная" является главным узлом по отношению к текущему.

Обмен в "ручном" режиме можно производить при помощи кнопок "Записать изменения" и "Прочитать
изменения". В первом случае будет предложено выбрать файл, куда изменения будут записаны, во втором
- файл, откуда изменения будут считаны. Обмен ведется в формате xml. Изменения записываются для
выбранного узла.

Шаг 2. Выгрузка изменений в XML-файл и отправка по электронной почте

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

Процедуру для работы с электронной почтой сделаем универсальной, т.е. сделаем возможным
использование как MAPI (отправка-получение через почтового клиента, например, MS Outlook), так и
прямое обращение к SMTP/POP3 серверам.

Добавим в конфигурацию несколько констант:

где-нибудь в общей форме обеспечиваем редактирование значений этих констант.

Добавим общий модуль, назовем его "рбРаспределеннаяБаза". В нем пишем:

Рекомендую в интерфейс добавить дополнительную панель, на одну из кнопок которой повесить вызов этой
процедуры. Теперь осталось запустить Предприятие, настроить электронный адрес периферийной ИБ,
поставить галку "Выполнять обмен", нажать на кнопку процедуры на панели и бежать получать почту для
указанного эл. адреса. Должно придти письмо с темой "1С:Обмен AA_BB" и вложенным файлом
"Message_AA_BB.xml".

Шаг 3. Получение обновлений по электронной почте и запись их в ИБ

Теперь займемся обратной процедурой: получение обновлений по электронной почте и запись их в ИБ.

В параметры сеанса добавим параметр "ИдетОбменРаспределеннойБазы" типа Булево. Ниже я объясню его
назначение.

Добавим в общий модуль рбРаспределеннаяБаза такую процедуру:

Теперь в интерфейсе на нашей панели добавляем еще одну кнопку, на которую вешаем вызов этой
процедуры. Запускаем Предприятие и наслаждаемся.
Почти все сделано, осталась малость: заставить наши процедуры выполняться в автоматическом режиме.
Шаг 4. Настройка автоматического обмена

Итак, мы почти вплотную приблизились к цели нашего повествования. Остался всего один шаг: запустить
выполнение процедур обмена в автоматическом режиме. Приступим.

Добавим константу ИнтервалАвтообменаРаспределеннойБазы типа Число(5,0).

В настройки пользователя добавим параметр ВыполнятьОбменРаспределенныхБаз. Для конфигурации
"Управление торговлей" это делается так:

* В план видов характеристик "НастройкиПользователей" добавим предопределенную
характеристику ВыполнятьОбменРаспределенныхБаз типа Булево.
* В форме элемента справочника "Пользователи" настраиваем изменение этого параметра (как это
сделать можно посмотреть в модуле формы, по аналогии с остальными параметрами).

В модуль рбРаспределеннаяБаза добавляем процедуру:

в модуль приложения:

в процедуру ПриНачалеРаботыСистемы() модуля приложения добавим такие строки:

(после подключения торгового оборудования)
.

Добавим на нашу панель еще пару кнопок для управления процессом: на одну вешаем процедуру
ПроверитьПодключениеАвтообмена(), на другую - ОтключитьАвтообмен()

Запускаем предприятие, настраиваем свойства пользователя и интервал автообмена и все!

Теперь при заходе в базу под этим-самым-настроенным пользователем будет запускаться обработчик
ожидания ВыполнитьАвтообмен(). Естественно, в периферийной базе тоже нужно настроить пользователя
для обмена.

Еще одно маленькое, но важное замечание:

1cv8.exe CONFIG /F<путь к ИБ> /N<Пользователь> /P<Пароль> /UpdateIBCfg

Использование веб-сервисов платформы 1С:Предприятие набирает обороты для решения задач интеграции: обмены данными между базами, взаимодействие с мобильными или веб-приложениями и многое другое. Огромные возможности могут покрыть любые потребности при решении задач интеграции. Если Вы разрабатываете веб-сервисы для интеграции больших / высоконагруженных баз, то возможно описанная здесь проблема будет уже не новой.

30 МБ, а для Apache

16 МБ. На счет Apache могу ошибаться, т.к. при установках стандартные настройки были разными.


Быстрое решение

1. Настройка через диспетчер служб IIS:

2. Изменение файла "web.config" в корне директории веб-приложения:


<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="1048576000" />
</requestFiltering>
</security>
</system.webServer>

3. В командной строке выполнить:

appcmd set config "Default Web Site" -section:requestFiltering -requestLimits.maxAllowedContentLength:1048576000 -commitpath:apphost

Правильное решение
В случаях, когда размер передаваемого пакета значительно больше установленных по умолчанию ограничений, изменять конфигурацию веб-сервера не рекомендую. Если заставить принимать веб-сервер пакеты в несколько гигабайт, то это может значительно повлиять на его производительность / работоспособность. Лучше всего сделать передачу большого пакета частями. Далее рассмотрим простейшую реализацию такого механизма на платформе 1С:Предприятие с использованием веб-сервисов.


Реализация
В тестовой конфигурации сделан пример веб-сервиса для передачи пакетов частями. Общий принцип следующий: через веб-сервис передаются части файла и записываются в регистр сведений. Для всех частей файла присваивается некоторый GUID, по которому файл можно будет "склеить" обратно, а также порядковый номер части. Наглядно передачу файла размером в 170 МБ по частям с размером 5 МБ можно представить так:

Для промежуточного сохранения частей файла используется регистр сведений. Передача файла через веб-сервис выполняется с использованием XDTO-пакетов следующей структуры:


Фактически пакет дублирует структуру регистра сведений:


Далее представлен обработчик метода веб-сервиса:

В качестве параметра метод веб-сервиса принимает объект с типом "MessagePartRequest" и передает из него данные в функцию "ЗафиксироватьПриемПакета". Эта функция сохраняет полученные через веб-сервис данные в базу:

Также в конфигурацию добавлен общий модуль ОбменДаннымиWS с функциями отправки и получения файла. Функция отправки файла разбивает его на части и передает каждую часть отдельно, обращаясь к веб-сервису:

Для получения исходного файла из сохраненных в регистре сведении его частей используется следующая функция:

Вот и все, такая простая реализация! Посмотрим на результат.

Проверка

Передача файла была продемонстрирована выше, теперь же давайте посмотрим на работоспособность функции получения ранее переданного файла.

Как видим, исходный файл получен с тем же размером. Задача выполнена!

Выводы

передача файлов большого объема по защищенному протоколу из 1С на сайт


Во время создания очередной B2B-системы на этапе интеграции 1С: Предприятие 8.2 с web — интерфейсом возникла необходимость безопасной передачи файлов больших размеров из 1С в web.
Для решения этой задачи был выбран протокол SFTP, как надежный и не имеющий ограничений по размеру передаваемого файла.
Во встроенном языке 1С: Предприятие 8.2 отсутствуют функции для передачи данных через SFTP, поэтому пришлось искать прикладные средства. На интернет-ресурсах, посвященных программированию 1С, есть примеры удачного использования freeware утилит типа WinSCP. Для использования данного способа необходимо из встроенного языка 1С выполнить запуск утилиты с параметрами командной строки.

Пример запуска утилиты WinCSP из 1С:

Минусом такого решения является отсутствие возможности контроля ошибок запуска и выполнения из встроенного языка 1С. В связи с этим было принято решение написать внешнюю DLL компоненту для 1С: Предприятие 8.2.

Создание компоненты DLL

  • IcomponentBase — реализует основные методы компоненты.
  • IlanguageInterface — служит для локализации методов и свойств 1С и С++ через определения массивов соответствий и методов акцессоров GetMethodName, GetPropName.

3. Для вызова необходимой функции из компоненты используется метод CallAsFunc из интерфейса IcomponentBase. При вызове методов из компоненты 1С, вызывается этот С++ метод.

  • lMethodNum – номер метода в массиве соответствий.
  • pvarRetValue – указатель на выходные параметры.
  • paParams — параметры из метода в 1С.
  • lSizeArray – размер массива, если входной параметр массив.

4. В нашем примере из 1С можно выполнять 4 метода, которым соответствуют С++ методы в DLL компоненте.

1С (методы) С++ методы
НачатьСессию()
Предварительно нужно определить параметры авторизации(хост, связку логин, пароль – либо rsa ключи, путь на удалённом сервере).
Поэтому функция НачатьСессию обрастает свойствами: Хост, Логин, Пароль, УдаленныйПуть
StartSSHSession(status,this->ssh_host,this->ssh_login,this->ssh_pass);
StartSftpSession(status,this->sftp_path)
ПослатьФайл(“Путь и имя файла на клиентской машине”)
WriteToServer(const char * &status, const char *loclfile)
ЕслиСессияНачата() isSessionStart()
ЗакончитьСессию() endSession() – завершает SFTP сеанс и SSH сеанс

5. В С++ нужно определить параметры доступа(чтение/запись) к созданным свойствам за это отвечают два метода IsPropReadable и IsPropWritable.

Таблица соотношений свойств 1С и С++

1С(свойства) С++ свойства
Хост ssh_host
Логин ssh_login
Пароль ssh_pass
УдаленныйПуть Sftp_path

Готовую библиотеку можно скачать тут.

Работа с компонентой во встроенном языке 1С

1. Выполняем подключение и создаем объект внешней компоненты, с помощью стандартных команд встроенного языка 1С.

2. Заполняем 4 свойства объекта компоненты Хост, Логин, Пароль, УдаленныйПуть.


3. Открываем сессию соединения


4. Отправляем файл


5. Отправляем следующий файл, с проверкой открыта ли сессия соединения.


6. После отправки файлов закрываем сессию

В результате выполнения успешно был передан файл с C:\data2.xml в /var/www/company/data/www/import/data.xml.

Вывод: данная реализация позволяет передавать файлы из 1С: Предприятие 8.2. большого размера по защищенному протоколу SFTP. Плюс появляется возможность переносить часть функционала из 1С во внешнюю компоненту, что защищает написанный код и позволяет реализовывать дополнительный, не доступный 1С функционал.

Механизм РИБ — механизм распределенных информационных баз - это когда у вас есть главная база и подчиненная(ые). Главная база может быть только одна, подчиненных может быть много. Каждая подчиненная база может иметь свои подчиненные базы, для которых она будет главной.

Вот посмотрим на картинку из первой ссылки по запросу в Яндексе:


РИБ используется для обмена данными. Причем не только теми данными, с которыми работает пользователь, но и данными изменения конфигурации. То есть РИБ позволяет передавать изменения конфигурации. Но изменить конфигурацию можно только в главной базе!

Визуализируем:

У нас большая компания и много филиалов. Есть доработанная УНФ, которую мы гордо называем УБФ(Управление Большой Фирмой). Но мы решили, что хватит терпеть то, что все филиалы имеют доступ к документам всех филиалов и каждому филиалу решили сделать отдельную базу, которую синхронизировать с нашей основной базой для передачи данных. Что ж, можно. Сделали.

И внезапно мы решили изменить картинку, которая появляется при входе в базу, захотели поместить туда логотип нашей фирмы, а почему бы и нет?

Как запилить картинку во все базы всех филиалов? Ну при текущем варианте, что у всех филиалов отдельная база, только руками. Руками специалистов, которые умеют заходить в конфигуратор и знают что нужно там нажать.

А вот если бы мы сделали подчиненные базы для филиалов, то есть использовали РИБ, то и данными бы обменивались, как при обычной синхронизации, и картинка бы сама добавилась во все "базы-дочки". Однако, в конфигуратор зайти бы все-таки пришлось, но только чтобы нажать кнопочку "Обновить конфигурацию базы данных", вот картинка:


Как создать подчиненную базу, на пальцах:

я буду использовать Управление торговлей, редакция 11 (11.4.13.275), но способ, в целом, одинаковый во всех типовых конфигурациях.

1) Сначала проделаем шаги, как при настройке обычной синхронизации:


2) . поставим галочку, нажмем.



4) тут ознакомимся с описанием. Я выберу обычную настройку, но если бы мы следовали примеру выше, то нужно было бы выбрать "с фильтром" и там одним кликом выбрать нужный филиал.



6) Указываем префикс - он будет подставляться к номерам документов, чтобы можно было отличить документы дочки и основной базы.



7) в общем случае, тут ничего не надо нажимать, кроме "Записать и закрыть".


8) А вот теперь создаем нашу новую подчиненную базу:


9) указываем место, куда ее покладем.





10) Зайдем в нашу новую подчиненную базу и закончим настройки синхронизации(синхронизация уже создалась, так как использовали РИБ, но нужно указать каталог для обмена выбрав "Настройки подключения")


(обратите внимание на верхний левый угол окна программы, там название базы, он отличается от предыдущих, так как это "дочка")

Кстати, в новой базе все пользователи будут выключены, пароли сброшены, нужно включить руками:


В общем-то ВСЕ.

Подчиненная база создана!

Теперь, когда наши программисты что-нибудь улучшат, эти улучшения прилетят в подчиненные базы сами.

Вот что-то изменили в основной базе:


нам нужно перенести изменения в базы-дочки.

Для этого запускаем главную базу в режиме 1С:Предприятие, то есть в пользовательском интерфейсе, заходим в настройки синхронизации, жмем выделенную кнопку:


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



После нажатия на Далее база закроется и начнет устанавливать обновления.


Когда обновы установятся, база начнет запускаться и сообщит нам следующее:


Это означает, что не обновлена конфигурация базы данных. Та самая маленькая кнопка в конфигураторе и это именно та причина, почему придется ОДИН раз зайти в конфигуратор. Что ж, зайдем в конфигуратор базы-дочки и нажмем эту кнопку, заодно вообще посмотрим что-да-как там, мы ж там еще не были.

Откроем конфигурацию и вот что увидим


Нажмем на "Обновить конфигурацию базы данных".

Увидим список изменений, которые прилетели с обновлениями:


И вот эти обновления появились в подчиненной базе.


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

Несколько правил:

1) Все узлы, кроме одного, должны иметь по одному главному узлу и один узел не будет иметь главного узла - это корневой узел.

2) Конфигурация может быть изменена только в узле, не имеющем главного узла (то есть в корневом).

3) Изменения конфигурации будут передаваться от главного к подчиненным узлам.

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

5) Сделать подчиненный узел в распределенной базе можно разными способами, но создание начального образа является рекомендуемым.

А теперь то, ради чего все писалось.

Как подчиненную базу сделать обычной(нормальной, отдельной, как хотите).

Я опишу только тот способ, которым пользуюсь. Это моя шпаргалка. Но он не единственный.

1) Заходим в свойства ярлыка запуска окна 1С:Предприятие:


2) В поле "Объект" дописываем:

DESIGNER /F"Путь до базы" /N"Имя Пользователя в базе" /P"Пароль пользователя" /ResetMasterNode

Читайте также: