В процессе администрирования и разработки на платформе 1С:Предприятие 8.3 часто возникает задача мониторинга активности пользователей. Это может быть необходимо для принудительного завершения работы перед обновлением конфигурации, выполнения функций в монопольном режиме, анализа нагрузки на сервер или ведения собственного журнала посещений. В рамках данной статьи мы подробно разберем несколько способов получения списка активных сеансов, проанализируем возможности встроенного языка и рассмотрим использование инструментов административного интерфейса.
Прежде чем переходить к написанию кода, давайте выясним причину частого недопонимания среди начинающих разработчиков. В системе 1С существует два принципиально разных списка:
Один и тот же пользователь может запустить несколько клиентских приложений (например, тонкий клиент и веб-клиент), что создаст несколько сеансов. Поэтому для получения «списка тех, кто сейчас в программе», нам необходимо работать именно с объектами типа СеансИнформационнойБазы.
Проанализируем самый простой и эффективный метод, доступный во встроенном языке 1С. Функция ПолучитьСеансыИнформационнойБазы() возвращает массив объектов, каждый из которых содержит информацию о конкретном подключении.
Рассмотрим пример кода, который выводит список всех активных пользователей в окно сообщений:
&НаСервере
Процедура ПолучитьСписокАктивныхСеансовНаСервере()
// Получаем массив всех активных сеансов
МассивСеансов = ПолучитьСеансыИнформационнойБазы();
Для Каждого ТекущийСеанс Из МассивСеансов Цикл
ИмяПользователя = ТекущийСеанс.Пользователь.Имя;
ВремяНачала = ТекущийСеанс.НачалоСеанса;
НомерСеанса = ТекущийСеанс.НомерСеанса;
ИмяКомпьютера = ТекущийСеанс.ИмяКомпьютера;
ТекстСообщения = СтрШаблон("Пользователь: %1, вошел в: %2, сеанс №: %3, ПК: %4",
ИмяПользователя, ВремяНачала, НомерСеанса, ИмяКомпьютера);
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ТекстСообщения);
КонецЦикла;
КонецПроцедуры
Важный момент: данный метод работает на стороне сервера. Объект СеансИнформационнойБазы содержит такие полезные свойства, как Приложение (позволяет узнать, зашел ли пользователь через Конфигуратор, Тонкий клиент или COM-соединение) и СоединениеСБД.
Если ваша конфигурация построена на базе БСП (что характерно для 1С:ERP, 1C:УТ 11 или 1С:Бухгалтерия 3.0, где активно используются дополнительные отчеты и обработки), рекомендуется использовать готовые механизмы подсистемы «Пользователи». Это упрощает поддержку кода, обеспечивает корректную работу с правами доступа и позволяет грамотно обрабатывать длительные операции в БСП.
Разберем, как получить таблицу активных пользователей с помощью вызова серверного метода БСП (для навигации по подобным процедурам удобно использовать MCP сервер для работы с экспортными функциями). Посмотрим на следующий пример:
&НаСервере
Функция ПолучитьТаблицуПользователейБСП()
// Используем программный интерфейс БСП
ТаблицаСеансов = СоединенияИСеансы.ПолучитьАктивныеСеансы();
// ТаблицаСеансов теперь содержит колонки:
// Пользователь, НачалоРаботы, ИмяКомпьютера, НомерСеанса
Возврат ТаблицаСеансов;
КонецФункции
Этот способ предпочтительнее, так как функции БСП уже учитывают многие нюансы, такие как разделение данных в облачных сервисах (Fresh) и фильтрацию фоновых заданий, которые часто засоряют список активных соединений.
В некоторых случаях встроенного языка недостаточно. Например, если нам нужно получить список пользователей во всех базах кластера или принудительно завершить сеанс другого пользователя, не имея доступа к самому приложению. В такой ситуации мы используем COM-объект для связи с сервером 1С.
Проанализируем ситуацию: нам необходимо подключиться к кластеру серверов и перечислить сеансы конкретной информационной базы. Помните, что для этого требуются права администратора кластера.
Процедура ПолучитьСеансыЧерезCOM(ИмяСервера, ПортКластера, ИмяБазыАдмин, ПарольБазыАдмин)
// Создаем соединитель
Connector = Новый COMОбъект("V83.COMConnector");
// Подключаемся к агенту сервера
Agent = Connector.ConnectAgent(ИмяСервера);
// Получаем кластеры (обычно используется первый в списке)
Clusters = Agent.GetClusters();
Cluster = Clusters.GetValue(0);
// Аутентификация в кластере
Agent.Authenticate(Cluster, "", "");
// Ищем нужную информационную базу по имени
WorkingProcesses = Agent.GetWorkingProcesses(Cluster);
Для Каждого Process Из WorkingProcesses Цикл
Если Process.Running Тогда
// Подключаемся к рабочему процессу
ConnectString = ИмяСервера + ":" + Формат(Process.MainPort, "ЧГ=0");
WorkingProcess = Connector.ConnectWorkingProcess(ConnectString);
// Находим описание базы
IBases = WorkingProcess.GetInfoBases();
Для Каждого IBase Из IBases Цикл
Если НРег(IBase.Name) = НРег(ИмяБазыАдмин) Тогда
// Получаем сеансы
Sessions = WorkingProcess.GetInfoBaseSessions(IBase);
Для Каждого Session Из Sessions Цикл
Сообщить("Сеанс пользователя: " + Session.UserName);
КонецЦикла;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Использование COM-соединения — это мощный инструмент, который позволяет управлять сеансами (метод TerminateSession), но он требует тщательной настройки прав доступа Windows и установленных библиотек 1С на стороне инициатора соединения.
При получении списка сеансов вы заметите большое количество записей с именами типа ФоновоеЗадание или пустые имена пользователей. Это нормальное поведение платформы 8.3, где многие процессы (индексация поиска, расчет себестоимости, обмен данными) выполняются в фоновом режиме.
Рассмотрим подробнее, как отфильтровать только «живых» пользователей, работающих в интерфейсе. Для этого мы проверяем свойство ИмяПриложения (или ApplicationName в COM). Нам интересны значения:
1CV8 — Толстый клиент;1CV8C — Тонкий клиент;WebClient — Веб-клиент.Если значение равно BackgroundJob, значит, этот сеанс инициирован сервером для выполнения регламентного задания.
Мы проанализировали основные методы получения информации об активных пользователях. Выбор метода зависит от вашей конкретной задачи:
ПолучитьСеансыИнформационнойБазы().Важно помнить: частое обращение к списку сеансов на высоконагруженных серверах может создавать кратковременные задержки, так как требует обращения к менеджеру кластера. Старайтесь кэшировать полученные данные, если они нужны вам для частого отображения в интерфейсе.