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