Как вызвать метод ЗаблокироватьРаботуПользователя() для выбранного пользователя при простое сеанса

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

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

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

Ограничение контекста платформенного метода

Проанализируем работу самого метода. В синтакс-помощнике указано, что процедура ЗаблокироватьРаботуПользователя() предназначена для интерактивной блокировки интерфейса текущего клиентского приложения и вызова стандартного окна авторизации. У метода есть ключевые особенности:

  1. Доступность только на клиенте: процедура исполняется исключительно в тонком, толстом или веб-клиенте. Ее невозможно вызвать в серверном модуле, общем модуле с признаком выполнения на сервере или в контексте регламентного фонового задания.
  2. Отсутствие параметров: метод не принимает имя пользователя, идентификатор или номер сеанса. Он всегда блокирует исключительно тот клиентский процесс, в контексте которого был вызван.

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

Архитектурная схема через регистр сведений и обработчик ожидания

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

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

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

Шаг 1. Хранение команд блокировки

Для передачи команды создадим непериодический независимый регистр сведений, например, КомандыБлокировкиСеансов. В структуру регистра включим следующие реквизиты:

  1. Пользователь (Измерение, тип СправочникСсылка.Пользователи).
  2. НомерСеанса (Измерение, тип Число) — крайне важно хранить именно номер сеанса из кластера, поскольку один и тот же пользователь может открыть несколько независимых баз или сессий. Блокировать нужно только простаивающую сессию.
  3. Заблокировать (Ресурс, тип Булево).

Посмотрим на пример кода серверной процедуры, которая после анализа активности сеансов делает запись в регистр сведений:


Процедура ЗарегистрироватьНеобходимостьБлокировки(ПользовательСсылка, НомерСеанса) Экспорт
    МенеджерЗаписи = РегистрыСведений.КомандыБлокировкиСеансов.СоздатьМенеджерЗаписи();
    МенеджерЗаписи.Пользователь = ПользовательСсылка;
    МенеджерЗаписи.НомерСеанса  = НомерСеанса;
    МенеджерЗаписи.Заблокировать = Истина;
    МенеджерЗаписи.Записать(Истина);
КонецПроцедуры

Шаг 2. Инициализация обработчика на стороне клиента

На стороне клиента необходимо запустить периодическую проверку. Для этого в модуле управляемого приложения в процедуре ПриНачалеРаботыСистемы подключаем клиентский обработчик ожидания:


Процедура ПриНачалеРаботыСистемы()
    // Подключаем проверку каждые 60 секунд
    ПодключитьОбработчикОжидания("ПроверитьНеобходимостьБлокировкиСеанса", 60);
КонецПроцедуры

Важный момент: не следует устанавливать слишком частый интервал (например, каждые 2-5 секунд), так как постоянные запросы от десятков пользователей создадут лишнюю паразитную нагрузку на СУБД. Интервала в 60–180 секунд вполне достаточно для отслеживания простоев.

Шаг 3. Проверка флага и вызов блокировки

В глобальном клиентском общем модуле или модуле приложения разместим процедуру проверки. Если сервер возвращает признак блокировки, сеанс сначала удаляет команду (чтобы не заблокироваться повторно после ввода пароля), а затем вызывает платформенное окно блокировки:


Процедура ПроверитьНеобходимостьБлокировкиСеанса() Экспорт
    Если ТребуетсяБлокировкаНаСервере() Тогда
        // Вызываем блокировку текущего клиентского сеанса
        ЗаблокироватьРаботуПользователя();
    КонецЕсли;
КонецПроцедуры

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


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

Нюансы анализа активности в кластере серверов

Проанализируем важную техническую проблему, с которой можно столкнуться при анализе параметра «Время последней активности» в консоли администрирования кластера или через COM-соединение:

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

Альтернативные архитектурные решения

В зависимости от конечной цели требования бизнеса можно выполнить более простыми и надежными средствами:

  1. Использование Системы взаимодействия: вместо периодического чтения данных из регистра сведений серверное фоновое задание может отправлять push-сообщение конкретному пользователю через Систему взаимодействия. Обработчик входящего сообщения на клиенте мгновенно сработает и вызовет ЗаблокироватьРаботуПользователя() без постоянных опросов базы данных.
  2. Клиентский таймер неактивности: вместо серверного фонового задания блокировку можно инициировать локально на клиенте. В обработчике ожидания клиент проверяет время, прошедшее с момента последнего действия пользователя в формах приложения, и блокирует сеанс при превышении порога.
  3. Штатные средства ОС (GPO): если цель заключается в защите экрана от посторонних глаз в офисе, наиболее корректное решение — настройка политик операционной системы Windows. Блокировка экрана рабочей станции по таймауту мыши и клавиатуры полностью решает задачу безопасности без доработки конфигурации 1С.
  4. Параметры информационной базы в кластере: если цель состоит в освобождении клиентских лицензий и оперативной памяти сервера, блокировка через ЗаблокироватьРаботуПользователя() не поможет, так как заблокированный сеанс продолжает удерживать лицензию. В этом случае правильнее настроить параметры базы в свойствах кластера: «Время засыпания пассивных сеансов» и «Время завершения спящих сеансов», либо принудительно завершать сеансы через утилиту RAS/RAC.
← На главную