Как передать оповещение конкретному пользователю из фонового или регламентного задания?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Метод 1: Использование механизма «Напоминания пользователя» из БСП

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

Проанализируем принцип работы этого метода. Суть заключается в том, что фоновое задание создает запись в специальном регистре, а клиентское приложение пользователя, имеющее встроенный обработчик, «подхватывает» эту запись и выводит окно напоминания.

Для реализации этого подхода в фоновом задании необходимо программно создать запись в регистре. Рассмотрим пример кода:


МенеджерЗаписи = РегистрыСведений.НапоминанияПользователя.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Пользователь = СсылкаНаНужногоПользователя;
МенеджерЗаписи.ВремяСобытия = ТекущаяДата();
МенеджерЗаписи.Содержание = "Фоновое задание по расчету себестоимости успешно завершено.";
МенеджерЗаписи.СрокНапоминания = ТекущаяДата(); // Момент, когда окно должно всплыть
МенеджерЗаписи.Источник = СсылкаНаОбъект; // Необязательно, ссылка на документ или отчет
МенеджерЗаписи.ИмяМетодаОповещения = "ОповещениеОбычное";
МенеджерЗаписи.Записать();

Разберем основные поля регистра НапоминанияПользователя:

Метод 2: Использование Системы взаимодействия

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

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


// Определяем пользователя, которому отправим сообщение
Участник = СистемаВзаимодействия.ПолучитьПользователя(НужныйПользователь.ИдентификаторПользователяИБ);

// Ищем существующее обсуждение или создаем новое (контекстное)
ВыборкаОбсуждений = СистемаВзаимодействия.ВыбратьОбсуждения(Новый Структура("Ключ", "УведомленияФоновыхЗаданий"));
Если ВыборкаОбсуждений.Следующий() Тогда
    Обсуждение = ВыборкаОбсуждений.ПолучитьОбсуждение();
Иначе
    Обсуждение = СистемаВзаимодействия.СоздатьОбсуждение();
    Обсуждение.Ключ = "УведомленияФоновыхЗаданий";
    Обсуждение.Участники.Добавить(Участник);
    Обсуждение.Записать();
КонецЕсли;

// Создаем и отправляем сообщение
Сообщение = СистемаВзаимодействия.СоздатьСообщение(Обсуждение.Идентификатор);
Сообщение.Текст = "Ваш отчет готов и доступен в разделе 'Мои документы'.";
Сообщение.Записать();

Важный нюанс: Чтобы пользователь увидел всплывающее уведомление, у него в настройках системы взаимодействия должно быть разрешено отображение оповещений. Преимущество этого метода в том, что сообщение доставляется мгновенно (push-технология), в то время как механизмы на регистрах работают с задержкой, определяемой интервалом опроса.

Метод 3: Реализация собственного механизма через обработчик ожидания

Если БСП не используется и Система взаимодействия не настроена, мы можем реализовать «велосипед», который, тем не менее, будет надежно работать. Проанализируем шаги реализации:

  1. Создание хранилища: Создадим простой регистр сведений ОчередьОповещений с измерениями Пользователь и реквизитами ТекстСообщения, Прочитано (Булево).
  2. Запись из фонового задания: В конце работы фонового задания просто добавляем запись в этот регистр для нужного пользователя.
  3. Клиентский опрос: В модуле управляемого приложения при старте системы подключаем обработчик ожидания.

Рассмотрим код подключения в модуле управляемого приложения:


Процедура ПриНачалеРаботыСистемы()
    ПодключитьОбработчикОжидания("ПроверитьНовыеОповещения", 60); // Проверка раз в минуту
КонецПроцедуры

Процедура ПроверитьНовыеОповещения() Экспорт
    // Вызываем серверный метод для проверки регистра
    ДанныеОповещения = МодульОповещенийСервер.ПолучитьНовоеОповещениеДляТекущегоПользователя();
    
    Если ДанныеОповещения <> Неопределено Тогда
        ПоказатьОповещениеПользователя("Внимание!", , ДанныеОповещения.Текст, БиблиотекаКартинок.Информация);
    КонецЕсли;
КонецПроцедуры

Рекомендация по оптимизации: Не устанавливайте слишком маленький интервал опроса (например, 1 секунду). Это может привести к существенному росту нагрузки на сервер БД, если в системе одновременно работают сотни пользователей. Оптимальный интервал — от 30 до 120 секунд.

Сравнение подходов

Разберем, какой метод выбрать в зависимости от ситуации:

Таким образом, для решения задачи передачи сообщения из «фонового» мира сервера в «видимый» мир пользователя всегда требуется промежуточное звено в виде базы данных или специализированного сервиса обмена сообщениями. Выбирайте метод исходя из архитектуры вашей конфигурации.

← На главную