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

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

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

В этой статье мы подробно разберем несколько вариантов решения этой задачи — от простых «костылей» до современных штатных механизмов платформы 1С и использования внешних компонент.

Вариант 1. Современное системное решение: Менеджер уведомлений клиента (Платформа 8.3.26 и выше)

Начиная с версии платформы 1С 8.3.26, разработчикам доступен долгожданный встроенный инструмент для отправки push-уведомлений с сервера на клиент без использования Системы взаимодействия — МенеджерУведомленийКлиента. Этот механизм идеально подходит для решения нашей задачи.

Рассмотрим по шагам, как настроить эту связку:

  1. На стороне клиента (в форме, которая должна принять данные): При открытии формы мы подключаем обработчик уведомлений, который будет ожидать наше событие. При закрытии формы — обязательно отключаем его.
  2. На стороне сервера (в коде Веб-сервиса или HTTP-сервиса): При получении данных от считывателя мы определяем нужный сеанс получателя и отправляем push-уведомление напрямую на клиент.

Разберем пример реализации клиентской части в модуле управляемой формы:


&НаКлиенте
Процедура ПриОткрытии(Отказ)
    // Подписываемся на событие получения данных RFID
    УведомленияКлиента.ПодключитьОбработчик("СобытиеСчитыванияRFID", "ОбработатьДанныеRFID");
КонецПроцедуры

&НаКлиенте
Процедура ПриЗакрытии(ЗавершениеРаботы)
    // Отключаем обработчик при закрытии формы
    УведомленияКлиента.ОтключитьОбработчик("СобытиеСчитыванияRFID", "ОбработатьДанныеRFID");
КонецПроцедуры

&НаКлиенте
Процедура ОбработатьДанныеRFID(ИмяСобытия, ПараметрыСобытия) Экспорт
    Если ИмяСобытия = "СобытиеСчитыванияRFID" Тогда
        // Обрабатываем полученную структуру данных
        КодМетки = ПараметрыСобытия.КодМетки;
        Сообщить("Успешно считана RFID-метка на клиенте: " + КодМетки);
    КонецЕсли;
КонецПроцедуры

Теперь посмотрим, как выглядит отправка сообщения из серверного метода нашего веб-сервиса:


Функция ОбработатьЗапросОтСчитывателя(ДанныеМетки, ИмяПользователяПолучателя) Экспорт
    
    // Формируем параметры события для отправки на клиент
    ПараметрыСобытия = Новый Структура;
    ПараметрыСобытия.Вставить("КодМетки", ДанныеМетки);
    
    // Определяем активный сеанс нужного пользователя
    МассивСеансов = Новый Массив;
    СоединенияИнформационнойБазы = ПолучитьСоединенияИнформационнойБазы();
    
    Для Каждого Соединение Из СоединенияИнформационнойБазы Цикл
        Если Соединение.ИмяПользователя = ИмяПользователяПолучателя Тогда
            МассивСеансов.Добавить(Соединение.НомерСеанса);
        КонецЕсли;
    КонецЦикла;
    
    // Если сеанс найден, отправляем push-уведомление
    Если МассивСеансов.Количество() > 0 Тогда
        УведомленияКлиента.ОтправитьУведомление("СобытиеСчитыванияRFID", ПараметрыСобытия, МассивСеансов);
    КонецЕсли;
    
КонецФункции

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

Вариант 2. Использование Системы взаимодействия (Платформы 8.3.10 – 8.3.25)

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

Рассмотрим логику реализации:

  1. В системе взаимодействия создается невидимый (технический) канал обсуждения для нашего процесса.
  2. Клиентская форма подписывается на новые сообщения в этом обсуждении.
  3. Веб-сервис, получая данные от RFID, отправляет сообщение в это обсуждение.
  4. Клиент ловит событие поступления нового сообщения, извлекает данные метки и обрабатывает их, отменяя стандартное отображение сообщения в чате.

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

Вариант 3. Периодический опрос через ОбработкуОжидания (Пулинг)

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

Чтобы минимизировать нагрузку на систему при таком подходе, спроектируем легкую схему:

  1. Создадим быстрый регистр сведений ОчередьСобытийОборудования с измерениями ИдентификаторСеанса (УникальныйИдентификатор) или Пользователь, и ресурсами ДанныеСобытия (Строка/ХранилищеЗначения) и Обработано (Булево).
  2. При получении данных веб-сервис записывает новую строку в этот регистр с привязкой к получателю.
  3. В форме запускается таймер через встроенный метод ПодключитьОбработчикОжидания().

Разберем пример кода для оптимизированного опроса:


&НаКлиенте
Процедура ПриОткрытии(Отказ)
    // Регистрируем наш уникальный идентификатор формы на сервере
    ИдентификаторФормы = Новый УникальныйИдентификатор;
    // Подключаем опрос раз в 1.5 секунды
    ПодключитьОбработчикОжидания("ПроверитьВходящиеСобытия", 1.5);
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьВходящиеСобытия()
    // Вызываем облегченный неконтекстный серверный метод
    ДанныеRFID = ПроверитьСобытияНаСервере(ИдентификаторФормы);
    
    Если ЗначениеЗаполнено(ДанныеRFID) Тогда
        // Обрабатываем данные на форме
        Сообщить("Получены данные через пулинг: " + ДанныеRFID);
    КонецЕсли;
КонецПроцедуры

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

Важное предупреждение: При использовании этого метода критически важно вызывать серверные процедуры с директивой &НаСервереБезКонтекста. Это убережет систему от постоянной передачи тяжелого контекста формы туда и обратно. Тем не менее, если количество одновременно работающих пользователей превышает 15–20 человек, постоянный опрос базы данных создаст заметную паразитную нагрузку на СУБД и процессор сервера приложений.

Вариант 4. Использование внешней компоненты (ВК) с локальным веб-сервером

Для создания полноценного асинхронного сценария по типу стандартного сканера штрихкодов ("ВнешнееСобытие") часто используют внешние компоненты.

Схема взаимодействия выглядит следующим образом:

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


&НаКлиенте
Процедура ВнешнееСобытие(Источник, Событие, Данные)
    Если Источник = "ЛокальныйRFIDАгент" И Событие = "СчитываниеМетки" Тогда
        Сообщить("Событие от внешней компоненты! Код метки: " + Данные);
        // Выполняем полезную работу
    КонецЕсли;
КонецПроцедуры

Преимущества метода: Полное отсутствие нагрузки на сервер 1С. Мгновенная реакция интерфейса. Решение работает локально и автономно.

Недостатки: Требуется разработка или покупка стабильной внешней компоненты, а также индивидуальная настройка сетевых доступов (маршрутизации портов) между RFID-оборудованием и компьютерами пользователей.

Резюме: что выбрать для вашего проекта?

Для правильного выбора архитектуры проанализируем масштаб вашей задачи:

← На главную