При разработке на платформе 1С:Предприятие 8.3 часто возникает ситуация, когда тяжелая операция выполняется в фоновом режиме, и по ее завершении необходимо уведомить конкретного пользователя. Прямой вызов процедуры ПоказатьОповещениеПользователя из фонового задания невозможен, так как фоновое задание выполняется на сервере и не имеет связи с клиентским интерфейсом. В этой статье мы разберем несколько эффективных способов решения этой задачи: от использования механизмов БСП до современных возможностей Системы взаимодействия.
Если ваша конфигурация построена на базе Библиотеки стандартных подсистем (БСП), самым правильным и надежным способом будет использование регистра сведений НапоминанияПользователя. Этот механизм уже содержит всю необходимую логику для отображения окон пользователю.
Проанализируем принцип работы этого метода. Суть заключается в том, что фоновое задание создает запись в специальном регистре, а клиентское приложение пользователя, имеющее встроенный обработчик, «подхватывает» эту запись и выводит окно напоминания.
Для реализации этого подхода в фоновом задании необходимо программно создать запись в регистре. Рассмотрим пример кода:
МенеджерЗаписи = РегистрыСведений.НапоминанияПользователя.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Пользователь = СсылкаНаНужногоПользователя;
МенеджерЗаписи.ВремяСобытия = ТекущаяДата();
МенеджерЗаписи.Содержание = "Фоновое задание по расчету себестоимости успешно завершено.";
МенеджерЗаписи.СрокНапоминания = ТекущаяДата(); // Момент, когда окно должно всплыть
МенеджерЗаписи.Источник = СсылкаНаОбъект; // Необязательно, ссылка на документ или отчет
МенеджерЗаписи.ИмяМетодаОповещения = "ОповещениеОбычное";
МенеджерЗаписи.Записать();
Разберем основные поля регистра НапоминанияПользователя:
Пользователи, которому адресовано сообщение.Это наиболее современный способ, который работает в режиме реального времени и не создает лишней нагрузки на базу данных постоянными опросами. Система взаимодействия позволяет серверному коду (в том числе фоновому заданию) отправить сообщение напрямую в клиентскую сессию пользователя.
Выясним, как программно отправить такое сообщение. Сначала нам нужно найти обсуждение между системой и пользователем или создать новое. Посмотрим на пример кода:
// Определяем пользователя, которому отправим сообщение
Участник = СистемаВзаимодействия.ПолучитьПользователя(НужныйПользователь.ИдентификаторПользователяИБ);
// Ищем существующее обсуждение или создаем новое (контекстное)
ВыборкаОбсуждений = СистемаВзаимодействия.ВыбратьОбсуждения(Новый Структура("Ключ", "УведомленияФоновыхЗаданий"));
Если ВыборкаОбсуждений.Следующий() Тогда
Обсуждение = ВыборкаОбсуждений.ПолучитьОбсуждение();
Иначе
Обсуждение = СистемаВзаимодействия.СоздатьОбсуждение();
Обсуждение.Ключ = "УведомленияФоновыхЗаданий";
Обсуждение.Участники.Добавить(Участник);
Обсуждение.Записать();
КонецЕсли;
// Создаем и отправляем сообщение
Сообщение = СистемаВзаимодействия.СоздатьСообщение(Обсуждение.Идентификатор);
Сообщение.Текст = "Ваш отчет готов и доступен в разделе 'Мои документы'.";
Сообщение.Записать();
Важный нюанс: Чтобы пользователь увидел всплывающее уведомление, у него в настройках системы взаимодействия должно быть разрешено отображение оповещений. Преимущество этого метода в том, что сообщение доставляется мгновенно (push-технология), в то время как механизмы на регистрах работают с задержкой, определяемой интервалом опроса.
Если БСП не используется и Система взаимодействия не настроена, мы можем реализовать «велосипед», который, тем не менее, будет надежно работать. Проанализируем шаги реализации:
ОчередьОповещений с измерениями Пользователь и реквизитами ТекстСообщения, Прочитано (Булево).Рассмотрим код подключения в модуле управляемого приложения:
Процедура ПриНачалеРаботыСистемы()
ПодключитьОбработчикОжидания("ПроверитьНовыеОповещения", 60); // Проверка раз в минуту
КонецПроцедуры
Процедура ПроверитьНовыеОповещения() Экспорт
// Вызываем серверный метод для проверки регистра
ДанныеОповещения = МодульОповещенийСервер.ПолучитьНовоеОповещениеДляТекущегоПользователя();
Если ДанныеОповещения <> Неопределено Тогда
ПоказатьОповещениеПользователя("Внимание!", , ДанныеОповещения.Текст, БиблиотекаКартинок.Информация);
КонецЕсли;
КонецПроцедуры
Рекомендация по оптимизации: Не устанавливайте слишком маленький интервал опроса (например, 1 секунду). Это может привести к существенному росту нагрузки на сервер БД, если в системе одновременно работают сотни пользователей. Оптимальный интервал — от 30 до 120 секунд.
Разберем, какой метод выбрать в зависимости от ситуации:
Таким образом, для решения задачи передачи сообщения из «фонового» мира сервера в «видимый» мир пользователя всегда требуется промежуточное звено в виде базы данных или специализированного сервиса обмена сообщениями. Выбирайте метод исходя из архитектуры вашей конфигурации.