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

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

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

Решение 1: Регистр сведений и обработчик ожидания (классический способ)

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

Проанализируем алгоритм по шагам:

  1. Создаем "почтовый ящик". В конфигурации необходимо создать новый регистр сведений, например, ОповещенияМеждуСеансами. Он будет служить централизованным хранилищем событий. Структура может быть следующей:
    • ИмяСобытия (Строка): Уникальное имя события, чтобы форма понимала, на что реагировать.
    • Источник (УникальныйИдентификатор): Идентификатор формы-источника события, чтобы не оповещать саму себя.
    • Параметры (ХранилищеЗначения): Здесь можно хранить любые данные, которые нужно передать (например, ссылку на измененный документ).
    • Дата (Дата): Время создания события, полезно для отладки и очистки.
  2. Подключаем обработчик ожидания. В каждой форме обработки, которая должна получать уведомления, при открытии (в процедуре ПриСозданииНаСервере) нужно запустить обработчик ожидания.
    
    // В модуле формы
    &НаСервере
    Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
        // Подключаем обработчик, который будет срабатывать каждые 5 секунд
        ПодключитьОбработчикОжидания("ПроверитьОповещения", 5, Ложь); 
    КонецПроцедуры
    
  3. Отправляем оповещение. В том месте, где происходит событие (например, по нажатию кнопки), мы программно создаем новую запись в нашем регистре сведений.
    
    &НаКлиенте
    Процедура ВыполнитьДействие(Команда)
        ВыполнитьДействиеНаСервере();
    КонецПроцедуры
    
    &НаСервере
    Процедура ВыполнитьДействиеНаСервере()
        // ... здесь выполняется основная логика ...
    
        // Отправляем оповещение всем остальным
        МенеджерЗаписи = РегистрыСведений.ОповещенияМеждуСеансами.СоздатьМенеджерЗаписи();
        МенеджерЗаписи.ИмяСобытия = "ОбновитьДанныеНаФорме";
        МенеджерЗаписи.Источник = УникальныйИдентификатор; // УникальныйИдентификатор формы
        МенеджерЗаписи.Записать();
    КонецПроцедуры
    
  4. Проверяем и реагируем. Процедура, подключенная как обработчик ожидания, будет периодически выполняться на сервере. Ее задача — проверить регистр, и если есть новые записи, выполнить нужные действия на клиенте.
    
    &НаСервере
    Процедура ПроверитьОповещения()
        Запрос = Новый Запрос;
        Запрос.Текст = 
            "ВЫБРАТЬ
            |   ОповещенияМеждуСеансами.Период,
            |   ОповещенияМеждуСеансами.ИмяСобытия
            |ИЗ
            |   РегистрСведений.ОповещенияМеждуСеансами КАК ОповещенияМеждуСеансами
            |ГДЕ
            |   ОповещенияМеждуСеансами.Источник <> &Источник";
        
        Запрос.УстановитьПараметр("Источник", УникальныйИдентификатор);
        
        Результат = Запрос.Выполнить();
        Если Не Результат.Пустой() Тогда
            // Нашли новые оповещения. Удаляем их, чтобы не сработать повторно.
            НаборЗаписей = РегистрыСведений.ОповещенияМеждуСеансами.СоздатьНаборЗаписей();
            НаборЗаписей.Отбор.Источник.Установить(УникальныйИдентификатор, ВидСравнения.НеРавно);
            НаборЗаписей.Прочитать();
            НаборЗаписей.Очистить();
            НаборЗаписей.Записать();
            
            // Оповещаем клиентскую часть формы для обновления
            Оповестить("ВыполнитьОбновлениеИнтерфейса");
        КонецЕсли;
    КонецПроцедуры
    
    &НаКлиенте
    Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
        Если ИмяСобытия = "ВыполнитьОбновлениеИнтерфейса" Тогда
            // Здесь вызываем процедуру, которая обновляет данные на форме
            ОбновитьФорму(); 
        КонецЕсли;
    КонецПроцедуры
    

Важные моменты:

Решение 2: Система взаимодействия (СВ)

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

Принцип работы:

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

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

Решение 3: Фоновые задания и хранилища

Этот метод является развитием первого способа и особенно полезен, когда операция, инициирующая оповещение, является длительной и ресурсоемкой. Чтобы не "замораживать" интерфейс пользователя, который ее запустил, основную логику выносят в фоновое задание.

Рассмотрим алгоритм:

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

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

Решение 4: Современные подходы (WebSocket и внешние сервисы)

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

WebSocket

Начиная с версии платформы 8.3.27, в 1С появилась встроенная поддержка протокола WebSocket. Это технология, созданная для постоянного двунаправленного соединения между клиентом и сервером. В отличие от метода с обработчиком ожидания, здесь не нужно постоянно "опрашивать" сервер. Сервер сам отправляет сообщение клиенту, как только оно появляется.

Этот способ является наиболее эффективным для систем с высокими требованиями к скорости реакции интерфейса.

Внешние сервисы и Webhooks

Идея заключается в использовании внешней системы как посредника. Например, сеанс 1С отправляет HTTP-запрос (вебхук) на адрес внешнего микросервиса. Однако здесь возникает ключевая сложность: как этот микросервис доставит оповещение обратно в другие клиентские сеансы 1С? Для этого ему все равно придется использовать один из вышеописанных механизмов: либо записать данные в регистр сведений 1С, либо (что более правильно) взаимодействовать с клиентами через WebSocket. Поэтому вебхуки чаще всего являются не самостоятельным решением, а частью более сложной архитектуры.

← На главную