Как реализовать мгновенное уведомление пользователя о создании новой записи в 1С без лишней нагрузки на систему

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

В практике разработки на платформе 1С часто возникает задача: один пользователь вносит изменения в базу данных (например, создает запись в Регистре сведений), а другой пользователь должен мгновенно получить об этом уведомление. Традиционный подход с использованием обработчика ожидания часто вызывает вопросы из-за потенциальной нагрузки на сервер и клиентское приложение, особенно при работе через веб-клиент. Разберем наиболее эффективные способы решения этой задачи для платформы 8.3.12 и выше.

Проблема межсессионного взаимодействия

Прежде всего, важно понимать ограничение встроенных механизмов оповещения. Метод Оповестить() и обработчик ОбработкаОповещения работают исключительно в рамках текущего клиентского сеанса. Если пользователь А вызывает этот метод, пользователь Б об этом не узнает, так как их сессии изолированы друг от друга. Проанализируем ситуацию: нам нужен механизм, который позволит серверу «протолкнуть» (push) информацию клиенту или заставит клиента максимально эффективно проверять наличие обновлений.

Решение 1: Система взаимодействия — современный стандарт

Для платформы версии 8.3.10 и выше самым правильным решением является использование Системы взаимодействия. Это встроенный механизм, который позволяет пользователям и приложениям обмениваться сообщениями в реальном времени. Главное преимущество этого метода для веб-клиента — использование технологии WebSocket, которая держит открытым одно соединение и мгновенно передает данные без постоянных повторных запросов к серверу.

Рассмотрим по шагам, как настроить программную отправку уведомления. Сначала нам необходимо отправить сообщение при записи в регистр. Для этого в модуле набора записей регистра или в обработке, создающей запись, пропишем следующий код:


// На стороне отправителя (Пользователь 1)
Участники = Новый Массив;
Участники.Добавить(НужныйПользовательСсылка); // Ссылка на пользователя-получателя

Обсуждение = СистемаВзаимодействия.СоздатьОбсуждение();
Обсуждение.Ключ = "УведомлениеОНовойЗаписи";
Обсуждение.Участники = Участники;
Обсуждение.Записать();

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

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


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

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

Решение 2: Оптимизированный обработчик ожидания

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

Проанализируем стратегию оптимизации: вместо опроса всего регистра мы будем проверять один-единственный «флаг» или дату последнего изменения. Рассмотрим алгоритм:

  1. Создадим вспомогательный объект (например, Константу или отдельный Регистр сведений из одной строки), где будет храниться только ДатаПоследнегоОбновления.
  2. При записи данных в основной регистр, пользователь №1 обновляет значение этой даты.
  3. Пользователь №2 в обработчике ожидания считывает только эту дату. Считывание одного значения из кэша или маленькой таблицы происходит практически мгновенно.
  4. Если дата в базе больше той, что была считана ранее, значит, данные изменились — и только тогда запускается основной код обработки.

Посмотрим на пример реализации «легкой» проверки:


// В форме на клиенте
Перем ПоследняяДатаПроверки;

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

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

Решение 3: Фоновые задания и очередь уведомлений

В обсуждении на форуме упоминалось использование фоновых заданий. Разберем, насколько это эффективно. Само по себе ФоновоеЗадание работает на сервере и не может напрямую взаимодействовать с интерфейсом пользователя (например, открыть форму или вывести Предупреждение). Однако оно может служить отличным инструментом для мониторинга сложных условий.

Представим ситуацию: уведомление должно срабатывать не просто при создании записи, а при выполнении сложного условия (например, если сумма в регистре превысила лимит). В этом случае:

Этот подход позволяет разгрузить клиентские сеансы от сложных вычислений, перенося логику анализа на сервер.

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

Мы проанализировали три основных подхода к реализации уведомлений. Для современных конфигураций на платформе 8.3.12 (особенно в веб-клиенте) безусловным фаворитом является Система взаимодействия. Она обеспечивает минимальную задержку и практически не создает лишнего трафика. Если же вы ограничены использованием обработчика ожидания, обязательно внедряйте механизм «флагов» или дат изменения, чтобы избежать деградации производительности сервера при большом количестве активных пользователей.

← На главную