Как в 1С реализовать разовое сообщение для всех открытых сеансов на управляемых формах?

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

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

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

Вариант 1. Классическая схема через Регистр Сведений и обработчик ожидания

Самый распространенный и интуитивно понятный способ — использование независимого регистра сведений. Рассмотрим, как правильно спроектировать структуру данных, чтобы избежать блокировок и лишней нагрузки.

Создадим независимый регистр сведений ОповещенияПользователей со следующей структурой:

  1. Измерение: Пользователь (Тип: СправочникСсылка.Пользователи).
  2. Измерение: ИдентификаторСообщения (Тип: Строка или УникальныйИдентификатор).
  3. Ресурс: Просмотрено (Тип: Булево).
  4. Ресурс: ДатаПросмотра (Тип: Дата).

Проанализируем алгоритм работы. При создании нового сообщения программно создаются записи в регистре для всех существующих пользователей с флагом Просмотрено = Ложь. На стороне клиента в модуле управляемого приложения мы подключаем обработчик ожидания.


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

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

Разберем важный момент, упомянутый в обсуждении: блокировки. Чтобы избежать проблем при одновременном чтении и записи множеством сеансов, используйте Управляемый режим блокировок. Чтение должно выполняться максимально быстро. Если мы используем схему с удалением записи после прочтения (как предлагали некоторые участники форума), это может быть эффективнее по объему данных, но лишает нас истории ознакомления.

Вариант 2. Оптимизация нагрузки с помощью параметров сеанса

Постоянный опрос базы данных (polling) из сотен клиентских сеансов каждые 30-60 секунд может заметно нагрузить SQL-сервер. Чтобы оптимизировать этот процесс, применим кэширование через параметры сеанса.

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

  1. При запуске системы считываем статус из регистра и записываем в параметр.
  2. В обработчике ожидания сначала проверяем параметр сеанса.
  3. Если в параметре Ложь, идем в базу, показываем сообщение и обновляем и параметр, и регистр.

Посмотрим на пример серверного кода:


Функция НужноЛиИдтиВБазу() Экспорт
    // Параметры сеанса работают очень быстро
    Возврат НЕ ПараметрыСеанса.АктуальноеОповещениеПросмотрено;
КонецФункции

Вариант 3. Использование справочника с табличной частью

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

Преимущества такого подхода:

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

Вариант 4. Современный метод: Система взаимодействия

Если ваша платформа версии 8.3.10 и выше, наиболее технологичным решением будет использование Системы взаимодействия. Это встроенный механизм, позволяющий реализовать Push-уведомления.

Рассмотрим, почему это лучше:

Для реализации нам понадобится использовать объект СистемаВзаимодействия. Пример отправки сообщения программно:


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

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

Вариант 5. Использование возможностей БСП

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

В частности, модуль ОповещенияПользователей позволяет создавать программные оповещения, которые всплывают в правом нижнем углу интерфейса «Такси». Это менее навязчиво, чем модальное окно Предупреждение, и соответствует современным стандартам UI-дизайна 1С.

Выводы и рекомендации

Подводя итоги, выберем оптимальный путь в зависимости от условий:

  1. Если важна простота реализации в самописной конфигурации — используйте независимый РегистрСведений + ПодключитьОбработчикОжидания. Обязательно добавьте поле «Срок актуальности», чтобы старые сообщения не всплывали у тех, кто не заходил в базу месяц.
  2. Если в базе много пользователей (более 50) — обязательно внедрите кэширование через ПараметрыСеанса, чтобы снизить нагрузку на СУБД.
  3. Если вы хотите сделать профессиональное решение и платформа позволяет — настраивайте Систему взаимодействия. Это обеспечит минимальный отклик и отсутствие лишнего трафика.
  4. Всегда отдавайте предпочтение методу ПоказатьОповещениеПользователя(). Оно не блокирует работу интерфейса, в отличие от модальных окон, которые в современных версиях платформы (в режиме «Без модальности») требуют написания сложных обратных вызовов (описания оповещения).

Мы проанализировали основные подходы к созданию системы разовых уведомлений. Выбор конкретного метода зависит от архитектуры вашей конфигурации и требований к производительности системы.

← На главную