При интеграции различных информационных систем на базе 1С программисты часто сталкиваются с проблемой: при вызове внешнего веб-сервиса (SOAP или HTTP) основной поток выполнения программы приостанавливается до момента получения ответа. Если сервис работает медленно или сеть нестабильна, пользователь видит «песочные часы», а система кажется зависшей. В этой статье мы подробно разберем, как реализовать немонопольное (асинхронное) обращение к веб-сервисам, используя различные подходы: от классических фоновых заданий до современных асинхронных методов платформы.
Самый очевидный и простой способ сделать вызов неблокирующим — это вынести процедуру обращения к сервису в фоновое задание. В этом случае основной сеанс пользователя продолжает работу, а сетевой обмен происходит в отдельном потоке на сервере 1С. Рассмотрим подробнее, как это реализовать.
Для этого нам необходимо создать экспортную процедуру в общем модуле (обязательно с установленными флажками «Сервер» и «Вызов сервера»). В этой процедуре будет описана вся логика подключения к WSПрокси или HTTPСоединение.
// В общем модуле (например, ИнтеграцияСервер)
Процедура ВыполнитьОбменССервисом(ПараметрыЗапроса) Экспорт
// Здесь создаем соединение и отправляем данные
Попытка
Определения = Новый WSОпределения(ПараметрыЗапроса.URL);
Прокси = Новый WSПрокси(Определения, ПараметрыЗапроса.URI, "ИмяСервиса", "ИмяПорта");
Результат = Прокси.ОтправитьДанные(ПараметрыЗапроса.Данные);
// Обработка результата или запись в лог
Исключение
ЗаписатьЛогОшибки(ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Теперь из формы или программного кода мы вызываем эту процедуру не напрямую, а через менеджер фоновых заданий:
ПараметрыВызова = Новый Структура("URL, Данные", "http://myservice.com/wsdl", ТекущиеДанные);
МассивПараметров = Новый Массив;
МассивПараметров.Добавить(ПараметрыВызова);
ФоновыеЗадания.Выполнить("ИнтеграцияСервер.ВыполнитьОбменССервисом", МассивПараметров, , "Обмен с веб-сервисом");
Проанализируем ситуацию: при таком подходе управление возвращается пользователю мгновенно. Однако возникает вопрос: как узнать, успешно ли прошел обмен? Для этого можно использовать механизмы оповещения или записывать результат в промежуточный регистр сведений.
Иногда проблема кроется не в 1С, а в том, что вызываемый веб-сервис сам по себе выполняет длительную операцию (например, проводит документы или формирует тяжелый отчет). В этом случае правильной архитектурной практикой будет разделение процесса на два этапа. Разберем по шагам, как это работает:
GUID).GUID.После этого клиентская база может либо периодически «спрашивать» о готовности (метод Polling), либо ожидать, пока вторая база сама вызовет ответный веб-сервис в первой базе (метод Callback). Посмотрим на пример логики получения результата через опрос:
// На стороне клиента периодически вызываем легкий метод
СтатусЗадачи = Прокси.ПолучитьСтатус(ИдентификаторЗадачи);
Если СтатусЗадачи = "Готово" Тогда
Результат = Прокси.ПолучитьРезультат(ИдентификаторЗадачи);
КонецЕсли;
Современные версии платформы 1С предоставляют встроенные инструменты для асинхронности. Вместо классического блокирующего метода Вызвать() или ОтправитьДляОбъекта(), мы можем использовать методы с префиксом Начать.... Выясним причину, почему это удобно: платформа сама берет на себя управление потоками, и вам не нужно вручную создавать фоновые задания.
Например, для HTTP-запросов используется объект HTTPСоединение и метод НачатьВыполнениеЗапроса. Процесс выглядит так:
ОписаниеОповещения, указывающее на процедуру, которая будет выполнена после получения ответа.
ОповещениеЗавершения = Новый ОписаниеОповещения("ОбработатьОтветСервера", ЭтотОбъект);
Соединение.НачатьВыполнениеЗапроса(ОповещениеЗавершения, Запрос);
// Здесь код выполняется СРАЗУ, интерфейс не блокируется
Важно помнить, что такие методы доступны преимущественно в управляемом приложении и требуют аккуратной работы с контекстом формы.
Если ваша система является высоконагруженной, то прямое соединение (Point-to-Point) между базами через веб-сервисы может стать «узким горлышком». В таких случаях рассмотрим подробнее использование посредников, таких как RabbitMQ или Apache Kafka.
Схема работы меняется кардинально:
Это полностью исключает проблему «зависания» базы-отправителя при недоступности или медлительности базы-приемника.
Если в вашей конфигурации используется Библиотека стандартных подсистем (БСП), проанализируем ситуацию с использованием модуля ДлительныеОперации. Это наиболее «цивилизованный» способ реализации асинхронности в экосистеме 1С.
Функция ДлительныеОперации.ЗапуститьВыполнениеНаСервере позволяет запустить любую процедуру в фоне и предоставляет готовый механизм для отслеживания состояния этого задания из формы. БСП берет на себя создание фонового задания, обработку исключений и передачу результата обратно в форму через обработчик ожидания.
// Пример запуска через БСП
ПараметрыПроцедуры = Новый Структура("Данные", МоиДанные);
РезультатЗапуска = ДлительныеОперации.ЗапуститьВыполнениеНаСервере(УникальныйИдентификатор,
"МойОбщийМодуль.ВыполнитьДлительныйОбмен", ПараметрыПроцедуры);
Если РезультатЗапуска.Статус = "Выполняется" Тогда
ИдентификаторЗадания = РезультатЗапуска.ИдентификаторЗадания;
// Подключаем обработчик ожидания для проверки статуса
КонецЕсли;
Независимо от выбранного способа, обязательно следует обращать внимание на следующие технические параметры:
HTTPСоединение или WSПрокси всегда указывайте таймаут (например, 10–20 секунд). Значение по умолчанию может быть слишком большим, что приведет к долгому ожиданию в случае «падения» канала связи.Попытка...Исключение. Внутри блока исключения обязательно записывайте подробности ошибки в ЖурналРегистрации, чтобы иметь возможность диагностировать проблемы связи.Подведем итог: для простых задач достаточно использования ФоновыеЗадания.Выполнить(). Если требуется сложная интеграция с гарантированной доставкой и высокой нагрузкой — смотрите в сторону очередей сообщений или паттерна «Квитанция». Использование асинхронных методов платформы и БСП сделает ваше решение более современным и устойчивым к сбоям.