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

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

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

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

Общая стратегия работы с серверными сообщениями

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

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

Рассмотрим подробнее конкретные механизмы реализации этой стратегии.

Использование встроенных механизмов 1С для оповещения

Метод Сообщить() и объект СообщениеПользователю

Начнем с базового механизма платформы — метода Сообщить() и связанного с ним объекта СообщениеПользователю. Эти средства предназначены для вывода информации пользователю. Когда вы используете Сообщить() в серверном коде, который был вызван непосредственно из клиентского контекста (например, при выполнении серверного вызова из формы), сообщение может быть доставлено пользователю. Однако, если код выполняется полностью асинхронно, например, в фоновом задании, этот метод не выведет сообщение напрямую на экран пользователя.

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

Давайте посмотрим на пример формирования сообщения в серверном модуле документа, который не записывается:


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

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

В этом примере, если процедура ПриЗаписиНаСервере вызывается напрямую из формы (например, при нажатии кнопки "Записать"), сообщения будут отображены пользователю. Однако, если документ записывается в фоновом задании, сообщения будут накапливаться и не будут сразу видны. Именно для таких сценариев нам и потребуются другие механизмы.

Фоновые задания и сбор сообщений

Фоновые задания — это краеугольный камень для выполнения длительных серверных операций в 1С без блокировки пользовательского интерфейса. Когда мы запускаем фоновое задание, оно работает на сервере в отдельном потоке. Для того чтобы получить сообщения из такого задания, мы используем механизм сбора сообщений, формируемых объектом СообщениеПользователю внутри фонового задания. Для этой задачи можно использовать пример выполнения длительных операций и отслеживания результата без БСП.

  1. Формирование сообщений в фоновом задании:

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

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

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

  2. Получение сообщений на клиенте:

    После запуска фонового задания, клиентское приложение должно "дождаться" его завершения или периодически опрашивать его состояние. Когда задание завершится (или даже в процессе выполнения для получения промежуточного прогресса), мы можем получить все накопленные сообщения с помощью метода ФоновоеЗадание.ПолучитьСообщенияПользователю().

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

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

Сервер взаимодействия 1С (Система взаимодействия)

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

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

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

Новый механизм уведомлений в 1С:Предприятие 8.3.26+

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

Этот механизм предоставляет прямой "push"-канал от сервера к клиенту. Основные принципы работы:

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

    КлючУведомления — это строка, по которой сервер будет знать, кому отправлять сообщение, а клиент — какой обработчик вызывать.

  3. Отправка уведомления с сервера: Сервер использует метод ОтправитьУведомление() объекта УведомленияКлиента для отправки сообщений.
    
    // Серверный модуль или фоновое задание
    // Например, после завершения длительной операции
    Процедура ЗавершитьОперациюИУведомитьПользователя(ПараметрыОперации, Результат) Экспорт
        // ... ваш код обработки результата ...
    
        МенеджерУведомлений = УведомленияКлиента;
        ДанныеДляКлиента = Новый Структура("Текст, ЕстьОшибки", "Загрузка данных успешно завершена.", Ложь);
        Если Результат.ЕстьОшибки Тогда
            ДанныеДляКлиента.Текст = "Загрузка данных завершена с ошибками: " + Результат.ОписаниеОшибок;
            ДанныеДляКлиента.ЕстьОшибки = Истина;
        КонецЕсли;
    
        // Определяем адресата
        // Если операция запущена из фонового задания, то у него есть НомерРодительскогоСеанса
        Если ПараметрыОперации.Свойство("НомерРодительскогоСеанса") И Не ПараметрыОперации.НомерРодительскогоСеанса = Неопределено Тогда
            Адресаты = Новый Массив();
            Адресаты.Добавить(ПараметрыОперации.НомерРодительскогоСеанса);
            МенеджерУведомлений.ОтправитьУведомление("КлючУведомления", ДанныеДляКлиента, Адресаты);
        Иначе
            // Отправляем всем активным сеансам, если это глобальное оповещение
            МенеджерУведомлений.ОтправитьУведомление("КлючУведомления", ДанныеДляКлиента);
        КонецЕсли;
    КонецПроцедуры
    

Особенно полезной эта возможность становится в связке с фоновыми заданиями: у объекта ФоновоеЗадание появилось свойство НомерРодительскогоСеанса (ParentSessionNumber), которое содержит номер сеанса, запустившего фоновое задание. Это позволяет нам отправлять уведомления конкретному клиенту, который ожидает результата выполнения длительной фоновой операции, минуя сложный механизм опроса.

Использование Библиотеки стандартных подсистем (БСП)

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

  1. ОбщегоНазначения.СообщитьПользователю(): Это обертка вокруг стандартного Сообщить(), которая может добавлять дополнительную логику, например, логирование или специальные режимы вывода.
    
    // Пример использования в серверном модуле
    Если Отказ Тогда
        ОбщегоНазначения.СообщитьПользователю("Документ не записан по причине: " + ПричинаОшибки, СтатусСообщения.Ошибка, "Форма", "Документ.Накладная.ФормаДокумента", ЭтаФорма);
    КонецЕсли;
    

    БСП-функции часто позволяют указать источник сообщения, что улучшает отладку и понимание пользователем контекста ошибки.

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

Альтернативные и гибридные подходы

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

Логирование и внешняя отправка

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

  1. Запись в Журнал регистрации 1С: Платформа 1С:Предприятие ведет свой собственный Журнал регистрации. Мы можем использовать процедуру ЗаписьЖурналаРегистрации() для записи информации, предупреждений или ошибок в этот журнал.
    
    // Пример записи ошибки в Журнал регистрации
    ЗаписьЖурналаРегистрации(
        "ЗагрузкаНакладных", // Имя события
        УровеньЖурналаРегистрации.Ошибка, // Уровень важности
        Метаданные.Документы.Накладная, // Объект метаданных, к которому относится событие
        Новая Структура("Номер", ДокументОбъект.Номер), // Дополнительные данные, например, номер документа
        "Не удалось записать накладную №" + ДокументОбъект.Номер + " по причине: " + ОписаниеОшибки() // Подробное сообщение
    );
    

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

  2. Запись в пользовательский лог-файл или специальный регистр: Мы можем создать собственный механизм логирования. Например, записывать все сообщения в текстовый файл или специальный регистр сведений в базе данных.
  3. Отправка лога средствами связи: После завершения фонового задания или серверной операции, мы можем собрать все накопленные сообщения (из лог-файла или регистра) и отправить их пользователю по электронной почте, SMS или через Telegram-бот.

    Для этого потребуется интеграция с внешними сервисами отправки почты (SMTP), SMS-шлюзами или API Telegram. Это обеспечивает гибкость, но требует дополнительной настройки и разработки. Например, по завершении загрузки, система может автоматически сгенерировать письмо с отчетом об ошибках и отправить его на электронную почту пользователя.

Хранение сообщений в базе данных (регистрах)

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

  1. Аккумулировать сообщения независимо от сеанса: Сообщения сохраняются в базе данных, что делает их доступными для любого пользователя в любое время, независимо от того, был ли его сеанс активен в момент генерации сообщения.
  2. Гибкая фильтрация и отображение: Мы можем создавать отчеты, обработки или специальные формы для отображения этих сообщений, фильтруя их по пользователю, дате, типу сообщения, объекту, к которому относится сообщение, и статусу (прочитано/не прочитано).
  3. Пример структуры регистра:
    • Измерение: Пользователь (Ссылка на Справочник.Пользователи)
    • Измерение: ДатаВремяСообщения (Дата и время)
    • Измерение: КлючОбъекта (Строка или УникальныйИдентификатор, для привязки к конкретному документу или элементу справочника)
    • Ресурс: ТекстСообщения (Строка неограниченной длины)
    • Ресурс: ТипСообщения (Перечисление: Информация, Предупреждение, Ошибка)
    • Ресурс: Прочитано (Булево)

Механизм работы будет следующим: серверное фоновое задание записывает все свои сообщения в этот регистр. Клиентское приложение пользователя при запуске или периодически (с помощью обработчика ожидания) опрашивает этот регистр, ищет непрочитанные сообщения, адресованные текущему пользователю, и отображает их. После отображения статус сообщения может быть изменен на "Прочитано".


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

    НаборЗаписей = РегистрыСведений.СообщенияПользователям.СоздатьНаборЗаписей();
    Запись = НаборЗаписей.Добавить();
    Запись.Пользователь = ПользовательКому;
    Запись.ДатаВремяСообщения = ТекущаяДата();
    Запись.КлючОбъекта = КлючОбъекта;
    Запись.ТекстСообщения = Текст;
    Запись.ТипСообщения = Тип;
    Запись.Прочитано = Ложь;
    НаборЗаписей.Записать();
КонецПроцедуры

// На клиенте (например, в обработчике ожидания формы рабочего стола):
Процедура ПроверитьНовыеСообщения()
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |    СообщенияПользователям.ТекстСообщения,
        |    СообщенияПользователям.ТипСообщения,
        |    СообщенияПользователям.КлючОбъекта,
        |    СообщенияПользователям.ДатаВремяСообщения
        |ИЗ
        |    РегистрСведений.СообщенияПользователям КАК СообщенияПользователям
        |ГДЕ
        |    СообщенияПользователям.Пользователь = &ТекущийПользователь
        |    И СообщенияПользователям.Прочитано = ЛОЖЬ
        |УПОРЯДОЧИТЬ ПО
        |    СообщенияПользователям.ДатаВремяСообщения";
    
    Запрос.УстановитьПараметр("ТекущийПользователь", Пользователи.ТекущийПользователь());
    
    Выборка = Запрос.Выполнить().Выбрать();
    Пока Выборка.Следующий() Цикл
        // Отображаем сообщение
        ВывестиСообщениеНаКлиенте(Выборка.ТекстСообщения, Выборка.ТипСообщения);
        // Помечаем как прочитанное (лучше делать это в отдельной транзакции или после подтверждения пользователя)
        МенеджерСообщений.ПометитьСообщениеПрочитанным(Выборка.КлючОбъекта, Выборка.ДатаВремяСообщения, Пользователи.ТекущийПользователь());
    КонецЦикла;
КонецПроцедуры

Этот способ позволяет нам реализовать практически полноценную систему уведомлений внутри 1С.

Использование внешних микросервисов и Push-уведомлений

Для очень специфичных и сложных сценариев, например, когда требуется высокопроизводительная система "push"-уведомлений в реальном времени, или когда 1С интегрируется с мобильными приложениями, мы можем рассмотреть использование внешних микросервисов:

  1. HTTP-сервисы и WebSocket: 1С может взаимодействовать с внешним микросервисом (например, написанным на Python, Node.js, Go) по HTTP. Микросервис может использовать WebSocket для поддержания постоянного соединения с клиентскими приложениями (в том числе веб-клиентами 1С или даже сторонними приложениями) и отправлять им уведомления в реальном времени.
  2. Firebase Cloud Messaging (FCM): Для мобильных клиентов 1С или интегрированных мобильных приложений мы можем использовать сервисы push-уведомлений, такие как Firebase Cloud Messaging. 1С через HTTP-запросы может отправлять сообщения на сервер FCM, который затем доставляет их на мобильные устройства.

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

Важные аспекты при выборе решения

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

  1. Типы сообщений:
    • Терминирующие сообщения: Это сообщения об ошибках, которые требуют немедленной реакции пользователя и могут прервать дальнейшее выполнение операции до тех пор, пока пользователь не исправит проблему. Для таких сообщений часто подходят ПоказатьПредупреждение() или Сообщить() (в клиентском контексте) с типом "Ошибка".
    • Ознакомительные сообщения: Это информационные сообщения или предупреждения, которые не блокируют работу пользователя. Для них хорошо подходят ПоказатьОповещениеПользователя() (для ненавязчивых всплывающих уведомлений), вывод в специальную панель сообщений или в регистр.
    • Сообщения о прогрессе: Для длительных операций важно информировать пользователя о текущем статусе. Здесь подходят динамическое обновление прогресс-бара, текстовые сообщения о выполненных шагах или, в новых версиях 1С, специальные механизмы уведомлений.
  2. Производительность и нагрузка на сервер: Механизмы с периодическим опросом (polling) могут создавать значительную нагрузку на сервер при большом количестве активных пользователей. Новые механизмы уведомлений 8.3.26+ или push-сервисы более эффективны в этом плане.
  3. Удобство для пользователя: Сообщения должны быть понятными, своевременными и легкодоступными. Пользователь не должен "искать" информацию о результатах своей работы.
  4. Надежность доставки: Убедитесь, что выбранный механизм гарантирует доставку важных сообщений. Например, запись в регистр обеспечивает сохранение сообщений даже при сбое клиентского приложения.

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

← На главную