Как организовать самописный обмен данными между базами 1С:Управление торговлей 11 через HTTP-сервисы

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

Создание собственного механизма обмена данными между конфигурациями на платформе 1С:Предприятие 8.3 — это задача, требующая понимания не только работы HTTP-протокола, но и внутренней архитектуры регистрации изменений. В этой статье мы подробно разберем, как построить надежную систему обмена между двумя базами 1С:УТ 11, используя HTTPСервисы, формат JSON и механизмы планов обмена.

Выбор формата передачи данных: JSON против XML

Первый вопрос, который возникает при проектировании обмена: в каком виде передавать объекты? В современных реалиях формат JSON является стандартом де-факто для веб-коммуникаций. Проанализируем, почему это выгодно:

  1. Легкость: В отличие от XML, JSON не перегружен закрывающими тегами, что уменьшает объем передаваемого трафика.
  2. Типизация в 1С: Платформа предоставляет мощный инструмент — СериализаторXDTO. Несмотря на название, он отлично работает с JSON. Это позволяет нам не собирать структуру вручную, а автоматически превращать объекты 1С (Документы, Справочники) в текстовое представление.
  3. Простота отладки: Читать 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) от сервера-приемника. Рассмотрим логику процесса:

  1. Формируем пакет из 10–100 объектов (пакетная обработка ускоряет обмен).
  2. Отправляем POST-запрос на HTTPСервис приемника.
  3. Если ответ 200 — вызываем ПланыОбмена.УдалитьРегистрациюИзменений() для данного узла и номера сообщения.
  4. Если ответ отличный от 200 — оставляем регистрацию и повторяем попытку в следующем сеансе.

Асинхронность и предотвращение блокировок

Важный архитектурный момент: никогда не вызывайте 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); // Ошибка сервера
    КонецПопытки;
КонецФункции

Дополнительные оптимизации

Для высоконагруженных систем обмена полезно внедрить следующие механизмы:

  1. Сжатие GZIP: Перед отправкой JSON можно сжать. 1С поддерживает работу с ЧтениеZipФайла и ЗаписьZipФайла, а веб-серверы (Apache/IIS) умеют на лету распаковывать такие запросы. Это сокращает объем данных в 5–7 раз.
  2. Идемпотентность: Передавайте в заголовке или теле запроса уникальный идентификатор пакета. Если приемник получит тот же пакет дважды (из-за сбоя подтверждения), он должен просто вернуть "ОК", не выполняя повторную запись в БД.
  3. Логирование: Обязательно записывайте в отдельный регистр или журнал регистрации результаты каждого сеанса обмена: сколько объектов отправлено, были ли ошибки и какой код ответа получен.

Таким образом, мы рассмотрели полный цикл создания самописного обмена. Сочетание надежности Планов обмена, гибкости JSON и производительности HTTP-сервисов позволяет создать систему, которая будет работать стабильно даже при больших объемах данных в 1С:УТ 11.

← На главную