Создание собственного механизма обмена данными между конфигурациями на платформе 1С:Предприятие 8.3 — это задача, требующая понимания не только работы HTTP-протокола, но и внутренней архитектуры регистрации изменений. В этой статье мы подробно разберем, как построить надежную систему обмена между двумя базами 1С:УТ 11, используя HTTPСервисы, формат JSON и механизмы планов обмена.
Первый вопрос, который возникает при проектировании обмена: в каком виде передавать объекты? В современных реалиях формат JSON является стандартом де-факто для веб-коммуникаций. Проанализируем, почему это выгодно:
XML, JSON не перегружен закрывающими тегами, что уменьшает объем передаваемого трафика.СериализаторXDTO. Несмотря на название, он отлично работает с JSON. Это позволяет нам не собирать структуру вручную, а автоматически превращать объекты 1С (Документы, Справочники) в текстовое представление.JSON-пакеты в логах или инструментах типа Postman значительно удобнее.Рассмотрим пример кода для сериализации объекта в JSON с использованием XDTO:
// На стороне отправителя
Функция ПолучитьДанныеОбъектаВJSON(СсылкаНаОбъект)
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
// Используем СериализаторXDTO для сохранения типов 1С
СериализаторXDTO.ЗаписатьJSON(ЗаписьJSON, СсылкаНаОбъект, НазначениеТипаXML.Явное);
Возврат ЗаписьJSON.Закрыть();
КонецФункции
Для того чтобы система знала, какие данные нужно отправить, нам необходим механизм отслеживания изменений. Рассмотрим два основных подхода, обсуждаемых специалистами.
Вариант 1: Использование стандартного Плана обмена. Это классический путь. Мы создаем ПланОбмена, включаем в него нужные документы и справочники. Платформа сама фиксирует изменения в специальных таблицах при записи объектов.
Вариант 2: Использование регистра сведений как очереди. Некоторые разработчики предпочитают создавать свой РегистрСведений, куда через подписки на события записывают ссылки на измененные объекты. Это может быть чуть быстрее при записи, но требует ручного управления «хвостами» и блокировками.
Проанализируем ситуацию: для большинства задач обмена 1 в 1 стандартный ПланОбмена является более надежным, так как он глубоко интегрирован в транзакционную модель 1С. Разберем по шагам, как работать с изменениями:
// Выборка изменений из плана обмена
УзелОбмена = ПланыОбмена.СинхронизацияЧерезHTTP.НайтиПоКоду("Приемник");
ВыборкаИзменений = ПланыОбмена.ВыбратьИзменения(УзелОбмена, НомерСообщения);
Пока ВыборкаИзменений.Следующий() Цикл
ДанныеОбъекта = ВыборкаИзменений.Получить();
// Формируем пакет и отправляем через HTTP
КонецЦикла;
Одной из ключевых проблем является риск потери данных при сбоях сети. Выясним причину, по которой нельзя удалять регистрацию сразу после вызова метода отправки. Если HTTPСервис приемника вернул ошибку или соединение разорвалось, данные в приемник не попали. Если мы уже очистили регистрацию в источнике, объект «зависнет» и больше никогда не будет отправлен.
Мы рекомендуем использовать подход «оптимистической очистки» только при получении успешного HTTP-статуса (200 OK) от сервера-приемника. Рассмотрим логику процесса:
POST-запрос на HTTPСервис приемника.ПланыОбмена.УдалитьРегистрациюИзменений() для данного узла и номера сообщения.Важный архитектурный момент: никогда не вызывайте HTTP-запрос напрямую в коде проведения документа. Рассмотрим подробнее, почему это опасно. Если сервер-приемник «зависнет» на 30 секунд, пользователь, проводящий накладную, будет ждать эти 30 секунд с заблокированной транзакцией. Это приведет к очередям и конфликтам блокировок в базе.
Правильная стратегия — использование фоновых заданий. Разберем шаги:
1. При записи объекта он просто регистрируется на плане обмена (это происходит мгновенно в рамках транзакции записи).
2. Специальное РегламентноеЗадание раз в минуту (или чаще) запускает процедуру отправки.
3. Эта процедура в фоновом режиме читает изменения, формирует HTTPСоединение и передает данные.
// Пример настройки HTTP-соединения
Соединение = Новый HTTPСоединение("192.168.1.100", , "User", "Password", , 30); // Таймаут 30 секунд
Запрос = Новый HTTPЗапрос("/base/hs/exchange/v1/data");
Запрос.УстановитьТелоИзСтроки(СтрокаJSON);
Попытка
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
Если Ответ.КодСостояния = 200 Тогда
// Очищаем регистрацию
КонецЕсли;
Исключение
// Запись в Журнал Регистрации ошибки связи
КонецПопытки;
На стороне базы-приемника необходимо создать HTTPСервис с методом POST. Внутри этого метода мы должны распарсить полученный JSON и записать данные. Важно помнить об использовании ОбменДанными.Загрузка = Истина, чтобы при загрузке не срабатывали лишние проверки и подписки на события, которые могут замедлить процесс или вызвать зацикливание обмена.
Проанализируем пример кода на стороне приемника:
Функция dataPOST(Запрос)
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(Запрос.ПолучитьТелоКакСтроку());
Попытка
// Читаем объект через XDTO
ОбъектЗагрузки = СериализаторXDTO.ПрочитатьJSON(ЧтениеJSON);
Если ТипЗнч(ОбъектЗагрузки) = Тип("ДокументОбъект.РеализацияТоваровУслуг") Тогда
ОбъектЗагрузки.ОбменДанными.Загрузка = Истина;
ОбъектЗагрузки.Записать();
КонецЕсли;
Возврат Новый HTTPСервисОтвет(200);
Исключение
Возврат Новый HTTPСервисОтвет(500); // Ошибка сервера
КонецПопытки;
КонецФункции
Для высоконагруженных систем обмена полезно внедрить следующие механизмы:
JSON можно сжать. 1С поддерживает работу с ЧтениеZipФайла и ЗаписьZipФайла, а веб-серверы (Apache/IIS) умеют на лету распаковывать такие запросы. Это сокращает объем данных в 5–7 раз.Таким образом, мы рассмотрели полный цикл создания самописного обмена. Сочетание надежности Планов обмена, гибкости JSON и производительности HTTP-сервисов позволяет создать систему, которая будет работать стабильно даже при больших объемах данных в 1С:УТ 11.