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