В практике разработки на платформе 1С:Предприятие часто возникает классическая задача: внешняя система (например, телефония, сайт, ERP-система или чат-бот) отправляет запрос на HTTP-сервис 1С. В результате этого запроса серверная часть 1С должна моментально «сгенерировать» действие в конкретном открытом сеансе пользователя — открыть форму, обновить динамический список, запустить локальный скрипт или вывести интерактивное предупреждение. Для автоматизации выполнения подобных операций в интерфейсе можно использовать платформу для визуального создания программных роботов.
Поскольку классическая архитектура «клиент-сервер» предполагает инициативу запросов исключительно со стороны клиента, прямое обращение сервера к запущенному сеансу пользователя долгое время вызывало сложности. В этой статье мы подробно проанализируем ситуацию, разберем базовые и продвинутые варианты решения данной задачи, а также рассмотрим новейшие нативные инструменты платформы 1С.
Это самый старый, проверенный временем, но при этом наименее производительный способ. Суть его заключается в организации буфера обмена (как правило, на базе регистра сведений) и периодического «опрашивания» этого буфера клиентом.
Схема работы решения:
ОчередьСобытийДляКлиентов), указывая получателем конкретного пользователя.Рассмотрим пример реализации клиентской части:
Процедура ПриНачалеРаботыСистемы() Экспорт
// Подключаем обработчик, который будет срабатывать каждые 10 секунд
ПодключитьОбработчикОжидания("ПроверитьНовыеСобытияСервера", 10, Ложь);
КонецПроцедуры
Процедура ПроверитьНовыеСобытияСервера() Экспорт
// Вызываем серверную функцию получения событий
СписокСобытий = ПолучитьНовыеСобытияИзРегистра();
Если СписокСобытий.Количество() > 0 Тогда
Для Каждого Событие Из СписокСобытий Цикл
ОбработатьВнешнееСобытиеНаКлиенте(Событие);
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Плюсы: простота реализации, надежность, сохранение истории событий в базе данных (если клиент не в сети, данные не пропадут и будут обработаны при следующем запуске). Такой механизм гарантированной доставки удобен, например, при отправке уведомлений о заказах Wildberries по схеме FBS.
Минусы: постоянная фоновая нагрузка на СУБД из-за регулярных запросов сотен пользователей. Либо мы получаем задержку в получении сообщений (если интервал большой), либо просадку производительности сервера (если интервал опроса слишком маленький).
Если вам требуется мгновенная реакция без лишней нагрузки на базу данных, правильным решением будет использование Системы взаимодействия (встроенный в платформу механизм мгновенных сообщений и видеозвонков).
Система взаимодействия работает по протоколу WebSocket. Это значит, что клиентское приложение поддерживает постоянное открытое TCP-соединение с сервером. Мы можем использовать так называемые служебные (неотображаемые) обсуждения.
Алгоритм настройки:
ПриПолученииСообщения, который выполняет нужные алгоритмы без какого-либо периодического опроса базы данных.Рассмотрим, как выглядит программная отправка сообщения с сервера:
// Серверный код (внутри метода HTTP-сервиса)
Процедура ОтправитьОповещениеПользователю(ИмяПользователя, ТекстОповещения) Экспорт
// Находим нужного пользователя системы взаимодействия
ПользовательСВ = СистемаВзаимодействия.ПолучитьПользователя(ИмяПользователя);
Если ПользовательСВ <> Неопределено Тогда
// Ищем существующее служебное обсуждение или создаем новое
ПараметрыОтбора = Новый ПараметрыОтбораОбсуждений;
ПараметрыОтбора.Ключ = "СлужебныйКанал_" + ИмяПользователя;
ВыборкаОбсуждений = СистемаВзаимодействия.ВыбратьОбсуждения(ПараметрыОтбора);
Если ВыборкаОбсуждений.Следующий() Тогда
Обсуждение = ВыборкаОбсуждений.Получить();
Иначе
Обсуждение = СистемаВзаимодействия.СоздатьОбсуждение();
Обсуждение.Ключ = "СлужебныйКанал_" + ИмяПользователя;
Обсуждение.Участники.Добавить(ПользовательСВ);
Обсуждение.Записать();
КонецЕсли;
// Создаем и отправляем сообщение
НовоеСообщение = СистемаВзаимодействия.СоздатьСообщение(Обсуждение.Идентификатор);
НовоеСообщение.Текст = ТекстОповещения;
НовоеСообщение.Записать();
КонецЕсли;
КонецПроцедуры
Плюсы: реакция системы происходит мгновенно (доли секунды), отсутствует лишняя нагрузка на сервер СУБД, используется полностью штатный инструмент платформы.
Минусы: требуется развертывание локального Сервера взаимодействия (1С:Сервер взаимодействия) либо подключение к бесплатному облачному сервису 1С.
В новых версиях платформы (начиная с релиза 8.3.26) разработчики 1С добавили долгожданный механизм гарантированной доставки уведомлений с сервера на клиент без использования Системы взаимодействия. Для этого в глобальном контексте появился менеджер УведомленияКлиента.
Этот механизм позволяет серверной части «проталкивать» данные непосредственно в конкретные сеансы пользователей.
Выясним, как работает этот механизм на практике. На стороне клиента мы регистрируем обработчик уведомлений:
// В модуле управляемого приложения на клиенте
Процедура ПриНачалеРаботыСистемы()
ОписаниеОповещения = Новый ОписаниеОповещения("ОбработатьСобытиеСервера", ЭтотОбъект);
УведомленияКлиента.ПодключитьОбработчик("ВнешнийЗапросHTTP", ОписаниеОповещения);
КонецПроцедуры
Процедура ОбработатьСобытиеСервера(ИмяУведомления, Данные, Источник) Экспорт
// Данные — это структура, переданная с сервера
ПоказатьПредупреждение(, "Внимание! Получено уведомление: " + Данные.Сообщение);
КонецПроцедуры
Теперь на сервере, когда отрабатывает наш HTTP-сервис, мы можем отправить данные конкретному пользователю. Для этого нам нужно знать номера его активных сеансов:
// На сервере в модуле HTTP-сервиса
Процедура ОповеститьСеансыПользователя(ИмяПользователя, ТекстСообщения)
ДанныеДляПередачи = Новый Структура("Сообщение", ТекстСообщения);
МассивНомеровСеансов = Новый Массив;
// Получаем список активных сеансов ИБ
СеансыИнформационнойБазы = ПолучитьСеансыИнформационнойБазы();
Для Каждого Сеанс Из СеансыИнформационнойБазы Цикл
Если Сеанс.Пользователь.Имя = ИмяПользователя Тогда
МассивНомеровСеансов.Добавить(Сеанс.НомерСеанса);
КонецЕсли;
КонецЦикла;
// Если сеансы найдены, отправляем push-уведомление напрямую в клиентское приложение
Если МассивНомеровСеансов.Количество() > 0 Тогда
УведомленияКлиента.ОтправитьУведомление("ВнешнийЗапросHTTP", ДанныеДляПередачи, МассивНомеровСеансов);
КонецЕсли;
КонецПроцедуры
Плюсы: революционный инструмент, не требующий стороннего ПО или Сервера взаимодействия. Работает «из коробки» на уровне платформы.
Минусы: требуется обновление платформы до версии не ниже 8.3.26. При переходе на новые релизы для регулярного обслуживания систем удобно использовать инструмент для автоматического обновления и тестирования баз 1С.
Разберем еще один сценарий. Что если внешнее событие генерируется вашим веб-сервером (например, на Node.js или Python), и вы хотите, чтобы клиентское приложение 1С самостоятельно держало постоянный дуплексный канал связи с этим внешним источником, минуя HTTP-сервисы самой 1С?
Начиная с версии платформы 8.3.27, в 1С появился нативный клиент WebSocket. Теперь нет необходимости использовать интеграцию через поле HTML-документа или внешние компоненты. Для удобного администрирования и мониторинга открытых сессий пригодится инструмент для управления WebSocket-соединениями.
Проанализируем пример подключения к внешнему сокет-серверу прямо из клиента 1С:
// Клиентский код
Перем Сокет;
Процедура ПодключитьWebSocket() Экспорт
// Инициализируем соединение с внешним сервером уведомлений
Сокет = Новый WebSocket("ws://192.168.1.100:8080/events");
// Описываем обработчики событий сокета
ДобавитьОбработчик(Сокет.ПриПолученииСообщения, "ПриПолученииСообщенияОтСокета");
ДобавитьОбработчик(Сокет.ПриОшибке, "ПриОшибкеСокета");
Сокет.Подключить();
КонецПроцедуры
Процедура ПриПолученииСообщенияОтСокета(Сообщение) Экспорт
// Обрабатываем сообщение, пришедшее из внешнего веб-сервера напрямую
ТекстСообщения = Сообщение.ПолучитьТекст();
ВыполнитьАлгоритмОповещения(ТекстСообщения);
КонецПроцедуры
Плюсы: прямое взаимодействие со сторонним ПО в реальном времени, высокая скорость работы, независимость от HTTP-сервисов 1С.
Минусы: требуется версия платформы 8.3.27 и выше, а также развернутый внешний WebSocket-сервер.
Выбор оптимального архитектурного решения зависит от используемой версии платформы 1С и требований к инфраструктуре:
УведомленияКлиента. Это избавит вас от лишней кодовой базы и сторонней инфраструктуры.