Сеанс.Connection

Свойства · Connection

Тип: Описание соединения, Неопределено. Содержит описание соединения, которому назначен сеанс. Иначе - Неопределено.

Полное описание, параметры и ограничения

Сеанс.Connection (ISessionInfo.Connection)

Сеанс (ISessionInfo)

Connection (Connection)

Доступен, начиная с версии 8.2.

Использование:
Только чтение.
Описание:
Тип: Описание соединения, Неопределено.
Содержит описание соединения, которому назначен сеанс. Иначе - Неопределено.
Доступность:

Интеграция.

Использование в версии:

Доступен, начиная с версии 8.2.

Методическая информация

Практические примеры

Разобраться, что такое сеанс, соединение и спящий клиент

На выбранном учебном сеансе читаем паспорт, политику сна и необязательное описание соединения без выгрузки имени пользователя или компьютера.

Где и как запускать

Учебная база: создайте серверный общий модуль УчебныеЗадачи (флаг Сервер). Код без директив вставьте в тело процедуры ВыполнитьПример() Экспорт. Вызовите её из серверного обработчика команды учебной обработки. Не запускайте в рабочей базе.

Подготовка

  1. Только собственный изолированный тестовый кластер на Windows. Зарегистрированная в нём база называется guide-owned-session-lab, имя конфигурации этой базы УчебнаяБазаСеансов. Запустите в ней отдельный учебный клиент.

  2. Создайте собственную обработку с управляемой формой. Вставьте весь код одного урока в модуль этой формы и свяжите команду Прочитать с обработчиком Прочитать. Серверная часть должна исполняться на Windows. Уроки заменяют весь модуль, а не добавляют шесть одинаковых функций.

  3. V85.COMConnector должен быть уже зарегистрирован администратором на Windows-сервере 1С с подходящей разрядностью. Пример ничего не устанавливает и не регистрирует. Если COM недоступен, остановитесь и обратитесь к администратору тестового стенда.

  4. В форме собственной обработки создайте строковые реквизиты КлючКластера, ИмяАгента, ПарольАгента, ИмяАдминистратора, ПарольАдминистратора и числовой НомерСеанса. Для полей паролей включите режим пароля, не сохраняйте значения в настройках формы.

  5. КлючКластера вручную возьмите из собственной консоли администрирования: имя кластера|имя сервера|основной порт, например Учебный|localhost|1541. Это порт кластера, не порт агента 1540 и не порт RAS 1545.

  6. Серверный код связывается только с агентом 127.0.0.1:1540 на том Windows-сервере, где исполняется модуль. Вводятся существующие учебные учётные данные агента и кластера; права и пароли не изменяются.

  7. Клиентский обработчик приведён полностью: он очищает поля паролей до вызова сервера и не печатает аргументы или технический текст ошибок. Это не гарантирует безопасное стирание строк из памяти; учебные учётные данные не должны сохраняться в настройках формы.

  8. Сначала НомерСеанса = 0: получите только ID и AppID сеансов этой учебной базы. Затем введите один ID из этого списка. ID уникален внутри информационной базы, а не во всём кластере.

  9. Ниже дан законченный серверный пример получения настоящего объекта Сеанс, а не функция, требующая неизвестный ИсходныйОбъект. COM и кластер при подготовке руководства не запускались; требуется ручной запуск на собственном стенде.

&НаКлиенте
Процедура Прочитать(Команда)
    ЛокальныйПарольАгента = ПарольАгента;
    ЛокальныйПарольАдминистратора = ПарольАдминистратора;
    ПарольАгента = "";
    ПарольАдминистратора = "";
    Попытка
        Отчет = ПрочитатьУчебныйСеанс(КлючКластера, ИмяАгента, ЛокальныйПарольАгента, ИмяАдминистратора, ЛокальныйПарольАдминистратора, НомерСеанса);
    Исключение
        ЛокальныйПарольАгента = "";
        ЛокальныйПарольАдминистратора = "";
        Сообщить("Чтение не выполнено. Проверьте собственный стенд, COM, ключ кластера, права и наличие выбранного сеанса. Технические сведения проверяет администратор стенда.");
        Возврат;
    КонецПопытки;
    ЛокальныйПарольАгента = "";
    ЛокальныйПарольАдминистратора = "";
    Сообщить(Отчет);
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПрочитатьУчебныйСеанс(КлючКластера, ИмяАгента, ПарольАгента, ИмяАдминистратора, ПарольАдминистратора, НомерСеанса)
    Если ПустаяСтрока(КлючКластера) Тогда
        ВызватьИсключение "Укажите точный ключ собственного тестового кластера";
    КонецЕсли;
    Если НомерСеанса < 0 Или Цел(НомерСеанса) <> НомерСеанса Тогда
        ВызватьИсключение "Номер сеанса должен быть целым неотрицательным числом";
    КонецЕсли;
    Соединитель = Новый COMОбъект("V85.COMConnector");
    Агент = Соединитель.ConnectAgent("127.0.0.1:1540");
    Агент.AuthenticateAgent(ИмяАгента, ПарольАгента);
    ПодходящиеКластеры = Новый Массив;
    Для Каждого Кандидат Из Агент.GetClusters() Цикл
        КлючКандидата = СтрШаблон("%1|%2|%3", Кандидат.ClusterName, Кандидат.HostName, Кандидат.MainPort);
        Если НРег(КлючКандидата) = НРег(КлючКластера) Тогда
            ПодходящиеКластеры.Добавить(Кандидат);
        КонецЕсли;
    КонецЦикла;
    Если ПодходящиеКластеры.Количество() <> 1 Тогда
        ВызватьИсключение "Собственный тестовый кластер не выбран однозначно";
    КонецЕсли;
    Кластер = ПодходящиеКластеры.Получить(0);
    Агент.Authenticate(Кластер, ИмяАдминистратора, ПарольАдминистратора);
    УчебныеБазы = Новый Массив;
    Для Каждого ОписаниеБазы Из Агент.GetInfoBases(Кластер) Цикл
        Если ОписаниеБазы.Name = "guide-owned-session-lab" Тогда
            УчебныеБазы.Добавить(ОписаниеБазы);
        КонецЕсли;
    КонецЦикла;
    Если УчебныеБазы.Количество() <> 1 Тогда
        ВызватьИсключение "Зарегистрированная учебная база не выбрана однозначно";
    КонецЕсли;
    УчебнаяБаза = УчебныеБазы.Получить(0);
    УчебныеСеансы = Агент.GetInfoBaseSessions(Кластер, УчебнаяБаза);
    СтрокиОтчета = Новый Массив;
    НайденныеСеансы = Новый Массив;
    Для Каждого КандидатСеанс Из УчебныеСеансы Цикл
        Если НомерСеанса = 0 Тогда
            СтрокиОтчета.Добавить(СтрШаблон("Сеанс %1; приложение %2", КандидатСеанс.SessionID, КандидатСеанс.AppID));
        ИначеЕсли КандидатСеанс.SessionID = НомерСеанса Тогда
            НайденныеСеансы.Добавить(КандидатСеанс);
        КонецЕсли;
    КонецЦикла;
    Если НомерСеанса = 0 Тогда
        Если СтрокиОтчета.Количество() = 0 Тогда
            Возврат "В учебной базе сейчас нет сеансов";
        КонецЕсли;
        Возврат СтрСоединить(СтрокиОтчета, Символы.ПС);
    КонецЕсли;
    Если НайденныеСеансы.Количество() <> 1 Тогда
        ВызватьИсключение "Учебный сеанс исчез или не выбран однозначно; обновите список";
    КонецЕсли;
    Сеанс = НайденныеСеансы.Получить(0);
    Если Сеанс.InfoBase.Name <> "guide-owned-session-lab" Тогда
        ВызватьИсключение "Сеанс не принадлежит выбранной учебной базе";
    КонецЕсли;
    СтрокиОтчета.Добавить(СтрШаблон("ID=%1; AppID=%2; язык интерфейса=%3", Сеанс.SessionID, Сеанс.AppID, Сеанс.Locale));
    СтрокиОтчета.Добавить(СтрШаблон("Начало=%1; последняя активность=%2", Сеанс.StartedAt, Сеанс.LastActiveAt));
    СтрокиОтчета.Добавить(СтрШаблон("Имя клиента заполнено=%1; имя пользователя заполнено=%2", Не ПустаяСтрока(Сеанс.Host), Не ПустаяСтрока(Сеанс.UserName)));
    СтрокиОтчета.Добавить(СтрШаблон("Описание учебной базы заполнено=%1", Не ПустаяСтрока(Сеанс.InfoBase.Descr)));
    СтрокиОтчета.Добавить(СтрШаблон("Спящий=%1; простой до сна, с=%2; сон до завершения, с=%3", Сеанс.Hibernate, Сеанс.PassiveSessionHibernateTime, Сеанс.HibernateSessionTerminateTime));
    СтрокиОтчета.Добавить(СтрШаблон("Есть рабочий процесс=%1; есть клиентская лицензия=%2", Сеанс.Process <> Неопределено, Сеанс.License <> Неопределено));
    Соединение = Сеанс.Connection;
    Если Соединение = Неопределено Тогда
        СтрокиОтчета.Добавить("Соединение сейчас не назначено; это допустимое состояние сеанса");
    Иначе
        СтрокиОтчета.Добавить(СтрШаблон("Соединение=%1; приложение=%2; установлено=%3", Соединение.ConnID, Соединение.Application, Соединение.ConnectedAt));
        СтрокиОтчета.Добавить(СтрШаблон("Связь с выбранным сеансом=%1; связь с учебной базой=%2", Соединение.SessionID = Сеанс.SessionID, Соединение.InfoBase.Name = "guide-owned-session-lab"));
        СтрокиОтчета.Добавить(СтрШаблон("Имя клиента соединения заполнено=%1; рабочий процесс назначен=%2; блокирующий ID=%3", Не ПустаяСтрока(Соединение.Host), Соединение.Process <> Неопределено, Соединение.blockedByLS));
    КонецЕсли;
    Возврат СтрСоединить(СтрокиОтчета, Символы.ПС);
КонецФункции

Разбор по шагам

  1. Сначала функция выбирает конкретный кластер и собственную зарегистрированную базу; только затем вызывает GetInfoBaseSessions.

  2. SessionID относится к базе. ConnID — номер соединения; он не заменяет SessionID. Сеанс и соединение — разные сущности.

  3. Connection/Process/License могут быть Неопределено; перед чтением вложенных свойств это проверяется.

  4. Оба тайм-аута сна заданы в секундах. Hibernate показывает текущее состояние, а не распоряжение завершить клиента.

  5. Locale — язык интерфейса и сообщений, не обещание регионального формата числа. Даты показываются как получены; часовой пояс не угадывается.

Как проверить результат

  1. При НомерСеанса=0 видны только номера и AppID собственной базы; для выбранного ID показан паспорт.

  2. Если соединение назначено, сравнения связи с сеансом и собственной базой ожидаются Истина. При конкурентном изменении состояния обновите снимок.

  3. Имя пользователя, адрес клиента, описание базы не публикуются; выводится лишь признак заполненности.

Ожидаемый результат

Новичок видит реальный сеанс и различает его необязательные связи и настройки сна.

На что обратить внимание

  1. Не считать спящий сеанс ошибочным и не завершать его ради учебного отчёта.

  2. Описание соединения — отдельный интерфейс с восемью свойствами, не интерфейс Соединение с другим набором полей.

  3. COM чтения не составляют транзакционный снимок; значения могли измениться между обращениями.

Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.

Прочитать блокировки своих сеансов и не подменить сеанс соединением

GetSessionLocks получает настоящий объект Сеанс из GetSessions. SessionID уникален в пределах конкретной базы, а не используется как глобальный объект-аргумент.

Где и как запускать

Полный модуль собственной управляемой формы нового локального Windows-стенда 1С 8.5.1.1343. Читаются только выбранный УчебныйКластер85 и подтверждённая УчебнаяБаза85. Здесь COM и BSL не запускались.

Подготовка

  1. Нужен отдельный собственный локальный серверный стенд 1С 8.5.1.1343 на Windows без рабочих баз. Здесь выполняется только авторская подготовка кода: реальное подключение агентом справочника не выполнялось.

  2. Администратор стенда заранее устанавливает сервер и регистрирует V85.COMConnector той же версии и разрядности, что серверный процесс учебной базы. Код не запускает regsvr32, не устанавливает платформу и не открывает COM 8.3 вместо 8.5.

  3. В своём стенде создайте единственный целевой кластер с точным именем УчебныйКластер85 и новую пустую серверную базу с именем УчебнаяБаза85. У описания этой базы задайте точное значение syntax-guide85:owned-com. Не переименовывайте рабочую базу или кластер ради обхода защит.

  4. У собственной учебной конфигурации задайте имя метаданных УчебнаяКонфигурацияСинтаксиса. Серверная функция должна выполняться на той же Windows-машине, что агент сервера и выбранный рабочий процесс: обращения жёстко ограничены 127.0.0.1.

  5. Заведите отдельные действительные учебные учётные данные администратора агента, администратора кластера и администратора базы с правом Администратор. В этих уроках имена и пароли намеренно должны быть непустыми; анонимный режим не используется.

  6. Создайте свою учебную обработку с управляемой формой. Реквизиты: ПортАгента и ПортКластера — Число без дробной части; КлючПроцесса, ИмяАгента, ПарольАгента, ИмяАдминистратораКластера, ПарольАдминистратораКластера, ИмяАдминистратораБазы, ПарольАдминистратораБазы, JSONРезультат — Строка; Занято — Булево, начально Ложь. Длина JSONРезультат 0.

  7. Поля трёх паролей выведите в Режиме пароля и не сохраняйте в настройках формы, истории или файле. JSONРезультат выведите многострочным полем только для просмотра. Добавьте команду ПолучитьУчебныйCOMСнимок с одноимённым клиентским обработчиком.

  8. Вставьте весь приведённый модуль формы, включая обе вспомогательные функции. ПортАгента берите из реальной настройки ragent, ПортКластера — из настройки менеджера кластера. Порт ras сюда не подходит.

  9. Первый раз оставьте КлючПроцесса пустым. Каталог покажет только локальные процессы выбранного учебного кластера. Скопируйте точный ключ порт|PID живого процесса из JSON, повторно введите очищенные пароли и повторите команду. PID не придумывайте; после перезапуска процесса получите каталог заново.

  10. Для диагностики соединений откройте одно или два своих клиентских окна УчебнаяБаза85 и выполните обычные учебные действия, например собственный константный запрос. Не создавайте нагрузку на рабочем сервере; измеряемые числа зависят от реальных действий.

  11. Снимок содержит только выбранные поля, не целые COM-объекты. Пароль СУБД, код разрешения входа, параметр блокировки и строка внешнего управления сеансами выводятся только как признаки наличия. Наличие строки не доказывает её корректность или доступность сервиса.

  12. Если вы сами запустите урок, произойдут административные обращения к своему локальному агенту и рабочему процессу. Настройки не меняются, сеансы не завершаются, база не создаётся и не удаляется. Здесь запуск в 1С и подключение не проверялись.

  13. Для наблюдения объектных блокировок в своей новой учебной конфигурации можно заранее создать справочник УчебныеТовары и собственный элемент Книга. Во втором своём учебном клиентском окне откройте его для редактирования; не проводите опыт с рабочими документами.

  14. Наличие блокировки не обещается в любой момент: режим редактирования, тип клиента и подготовка влияют на результат. Пустой список — допустимый фактический результат; код не создаёт искусственную блокировку ради ненулевого отчёта.

  15. Connection и Session у IObjectLock могут быть Неопределено. Если обе связи отсутствуют или принадлежность своей базе не подтверждена, описание объекта не публикуется.

&НаКлиенте
Процедура ПолучитьУчебныйCOMСнимок(Команда)
    Если Занято Тогда
        Возврат;
    КонецЕсли;
    Занято = Истина;
    Попытка
        JSONРезультат = УчебныйCOMСнимокНаСервере(ПортАгента, ПортКластера, КлючПроцесса,
            ИмяАгента, ПарольАгента, ИмяАдминистратораКластера, ПарольАдминистратораКластера,
            ИмяАдминистратораБазы, ПарольАдминистратораБазы);
    Исключение
        JSONРезультат = "Снимок не получен. Проверьте собственный Windows-стенд, COM 8.5, разрядность, порты, ключ процесса, учебные имена и права. Сырую ошибку с учётными данными не публикуйте.";
    КонецПопытки;
    ПарольАгента = "";
    ПарольАдминистратораКластера = "";
    ПарольАдминистратораБазы = "";
    Занято = Ложь;
КонецПроцедуры

&НаСервереБезКонтекста
Функция УчебныйCOMСнимокНаСервере(ПортАгента, ПортКластера, КлючПроцесса,
    ИмяАгента, ПарольАгента, ИмяАдминистратораКластера, ПарольАдминистратораКластера,
    ИмяАдминистратораБазы, ПарольАдминистратораБазы)
    Система = Новый СистемнаяИнформация;
    Если Система.ТипПлатформы <> ТипПлатформы.Windows_x86
        И Система.ТипПлатформы <> ТипПлатформы.Windows_x86_64 Тогда
        ВызватьИсключение "COM-урок требует серверного выполнения на Windows";
    КонецЕсли;
    Порты = Новый Массив;
    Порты.Добавить(ПортАгента);
    Порты.Добавить(ПортКластера);
    Для Каждого Порт Из Порты Цикл
        Если ТипЗнч(Порт) <> Тип("Число") Тогда
            ВызватьИсключение "Порты должны быть числами";
        КонецЕсли;
        Если Порт <> Цел(Порт) ИЛИ Порт < 1 ИЛИ Порт > 65535 Тогда
            ВызватьИсключение "Недопустимый порт локального стенда";
        КонецЕсли;
    КонецЦикла;
    Если ТипЗнч(КлючПроцесса) <> Тип("Строка") Тогда
        ВызватьИсключение "Ключ процесса должен быть строкой";
    КонецЕсли;
    УчётныеДанные = Новый Структура;
    УчётныеДанные.Вставить("ИмяАгента", ИмяАгента);
    УчётныеДанные.Вставить("ПарольАгента", ПарольАгента);
    УчётныеДанные.Вставить("ИмяКластера", ИмяАдминистратораКластера);
    УчётныеДанные.Вставить("ПарольКластера", ПарольАдминистратораКластера);
    УчётныеДанные.Вставить("ИмяБазы", ИмяАдминистратораБазы);
    УчётныеДанные.Вставить("ПарольБазы", ПарольАдминистратораБазы);
    Для Каждого Поле Из УчётныеДанные Цикл
        Если ТипЗнч(Поле.Значение) <> Тип("Строка") Тогда
            ВызватьИсключение "Учебные учётные данные должны быть строками";
        КонецЕсли;
        Если ПустаяСтрока(Поле.Значение) Тогда
            ВызватьИсключение "Введите все три непустые учебные пары учётных данных";
        КонецЕсли;
    КонецЦикла;
    ЛокальноеИмя = НРег(ИмяКомпьютера());
    АдресАгента = "tcp://127.0.0.1:" + Формат(ПортАгента, "ЧГ=0");
    Соединитель = Новый COMОбъект("V85.COMConnector");
    Агент = Соединитель.ConnectAgent(АдресАгента);
    Если Агент.ConnectionString <> АдресАгента Тогда
        ВызватьИсключение "Не совпала строка выбранного локального подключения";
    КонецЕсли;
    Агент.AuthenticateAgent(ИмяАгента, ПарольАгента);
    Кластер = Неопределено;
    СовпаденийКластера = 0;
    Для Каждого Найденный Из Агент.GetClusters() Цикл
        Если Найденный.ClusterName = "УчебныйКластер85"
            И УчебныйЛокальныйУзел(Найденный.HostName, ЛокальноеИмя)
            И Найденный.MainPort = ПортКластера Тогда
            Кластер = Найденный;
            СовпаденийКластера = СовпаденийКластера + 1;
        КонецЕсли;
    КонецЦикла;
    Если СовпаденийКластера <> 1 Тогда
        ВызватьИсключение "Нужен единственный собственный локальный УчебныйКластер85 с указанным портом";
    КонецЕсли;
    Агент.Authenticate(Кластер, ИмяАдминистратораКластера, ПарольАдминистратораКластера);
    КраткаяБаза = Неопределено;
    СовпаденийБазы = 0;
    Для Каждого НайденнаяБаза Из Агент.GetInfoBases(Кластер) Цикл
        Если НайденнаяБаза.Name = "УчебнаяБаза85" И НайденнаяБаза.Descr = "syntax-guide85:owned-com" Тогда
            КраткаяБаза = НайденнаяБаза;
            СовпаденийБазы = СовпаденийБазы + 1;
        КонецЕсли;
    КонецЦикла;
    Если СовпаденийБазы <> 1 Тогда
        ВызватьИсключение "Не найдена единственная собственная база с точным маркером описания";
    КонецЕсли;
    Каталог = Новый Массив;
    Процесс = Неопределено;
    СовпаденийПроцесса = 0;
    Для Каждого НайденныйПроцесс Из Агент.GetWorkingProcesses(Кластер) Цикл
        Если УчебныйЛокальныйУзел(НайденныйПроцесс.HostName, ЛокальноеИмя)
            И НайденныйПроцесс.MainPort >= 1 И НайденныйПроцесс.MainPort <= 65535
            И НайденныйПроцесс.MainPort = Цел(НайденныйПроцесс.MainPort)
            И НЕ ПустаяСтрока(НайденныйПроцесс.PID) Тогда
            Ключ = Формат(НайденныйПроцесс.MainPort, "ЧГ=0") + "|" + НайденныйПроцесс.PID;
            Каталог.Добавить(Новый Структура("Ключ,Хост", Ключ, НайденныйПроцесс.HostName));
            Если Ключ = КлючПроцесса Тогда
                Процесс = НайденныйПроцесс;
                СовпаденийПроцесса = СовпаденийПроцесса + 1;
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
    Если ПустаяСтрока(КлючПроцесса) Тогда
        Возврат СериализоватьСвойСнимок(Новый Структура("УчебныеПроцессы", Каталог));
    КонецЕсли;
    Если СовпаденийПроцесса <> 1 Тогда
        ВызватьИсключение "Нужен один живой локальный процесс с ключом из своего каталога";
    КонецЕсли;
    РабочееСоединение = Соединитель.ConnectWorkingProcess("tcp://127.0.0.1:" + Формат(Процесс.MainPort, "ЧГ=0"));
    СовпаденийПолнойБазы = 0;
    Для Каждого НайденнаяПолнаяБаза Из РабочееСоединение.GetInfoBases() Цикл
        Если НайденнаяПолнаяБаза.Name = КраткаяБаза.Name И НайденнаяПолнаяБаза.Descr = КраткаяБаза.Descr Тогда
            СовпаденийПолнойБазы = СовпаденийПолнойБазы + 1;
        КонецЕсли;
    КонецЦикла;
    Если СовпаденийПолнойБазы <> 1 Тогда
        ВызватьИсключение "Рабочий процесс не подтвердил свою учебную базу";
    КонецЕсли;
    РабочееСоединение.AddAuthentication(ИмяАдминистратораБазы, ПарольАдминистратораБазы);
    База = Неопределено;
    СовпаденийПослеВхода = 0;
    Для Каждого НайденнаяПослеВхода Из РабочееСоединение.GetInfoBases() Цикл
        Если НайденнаяПослеВхода.Name = "УчебнаяБаза85" И НайденнаяПослеВхода.Descr = "syntax-guide85:owned-com" Тогда
            База = НайденнаяПослеВхода;
            СовпаденийПослеВхода = СовпаденийПослеВхода + 1;
        КонецЕсли;
    КонецЦикла;
    Если СовпаденийПослеВхода <> 1 Тогда
        ВызватьИсключение "После аутентификации изменился выбор учебной базы";
    КонецЕсли;
    Снимок = Новый Структура;
    Снимок.Вставить("База", База.Name);
    Снимок.Вставить("ПроцессPID", Процесс.PID);
    Снимок.Вставить("ПортПроцесса", Процесс.MainPort);
    Сеансы = Новый Массив;
    Для Каждого УчебныйСеанс Из Агент.GetSessions(Кластер) Цикл
        Если УчебныйСеанс.InfoBase.Name <> КраткаяБаза.Name ИЛИ УчебныйСеанс.InfoBase.Descr <> КраткаяБаза.Descr Тогда
            Продолжить;
        КонецЕсли;
        СтрокаСеанса = Новый Структура;
        СтрокаСеанса.Вставить("SessionID", УчебныйСеанс.SessionID);
        СтрокаСеанса.Вставить("ЕстьАктивноеСоединение", УчебныйСеанс.Connection <> Неопределено);
        СтрокиБлокировок = Новый Массив;
        Для Каждого Блокировка Из Агент.GetSessionLocks(Кластер, УчебныйСеанс) Цикл
            СтрокаБлокировки = УчебнаяСтрокаБлокировки(Блокировка, КраткаяБаза.Name, КраткаяБаза.Descr);
            Если СтрокаБлокировки <> Неопределено Тогда
                СтрокиБлокировок.Добавить(СтрокаБлокировки);
            КонецЕсли;
        КонецЦикла;
        СтрокаСеанса.Вставить("Блокировки", СтрокиБлокировок);
        СтрокаСеанса.Вставить("Количество", СтрокиБлокировок.Количество());
        Сеансы.Добавить(СтрокаСеанса);
    КонецЦикла;
    Снимок.Вставить("СвоиСеансы", Сеансы);
    Возврат СериализоватьСвойСнимок(Снимок);
КонецФункции

&НаСервереБезКонтекста
Функция СериализоватьСвойСнимок(Снимок)
    Писатель = Новый ЗаписьJSON;
    Писатель.УстановитьСтроку();
    ЗаписатьJSON(Писатель, Снимок);
    Возврат Писатель.Закрыть();
КонецФункции


&НаСервереБезКонтекста
Функция УчебныйЛокальныйУзел(ИмяУзла, ЛокальноеИмя)
    Возврат НРег(ИмяУзла) = ЛокальноеИмя ИЛИ НРег(ИмяУзла) = "localhost" ИЛИ ИмяУзла = "127.0.0.1";
КонецФункции


&НаСервереБезКонтекста
Функция УчебнаяСтрокаБлокировки(Блокировка, ИмяБазы, МаркерБазы)
    СтрокаБлокировки = Новый Структура;
    ОтнесенаКБазе = Ложь;
    СоединениеБлокировки = Блокировка.Connection;
    СеансБлокировки = Блокировка.Session;
    Если СоединениеБлокировки <> Неопределено Тогда
        Если СоединениеБлокировки.InfoBase.Name <> ИмяБазы ИЛИ СоединениеБлокировки.InfoBase.Descr <> МаркерБазы Тогда
            Возврат Неопределено;
        КонецЕсли;
        ОтнесенаКБазе = Истина;
        СтрокаБлокировки.Вставить("ConnID", СоединениеБлокировки.ConnID);
    КонецЕсли;
    Если СеансБлокировки <> Неопределено Тогда
        Если СеансБлокировки.InfoBase.Name <> ИмяБазы ИЛИ СеансБлокировки.InfoBase.Descr <> МаркерБазы Тогда
            Возврат Неопределено;
        КонецЕсли;
        ОтнесенаКБазе = Истина;
        СтрокаБлокировки.Вставить("SessionID", СеансБлокировки.SessionID);
    КонецЕсли;
    Если НЕ ОтнесенаКБазе Тогда
        Возврат Неопределено;
    КонецЕсли;
    СтрокаБлокировки.Вставить("ЕстьСоединение", СоединениеБлокировки <> Неопределено);
    СтрокаБлокировки.Вставить("ЕстьСеанс", СеансБлокировки <> Неопределено);
    СтрокаБлокировки.Вставить("Object", Блокировка.Object);
    СтрокаБлокировки.Вставить("LockDescr", Блокировка.LockDescr);
    СтрокаБлокировки.Вставить("LockedAt", XMLСтрока(Блокировка.LockedAt));
    Возврат СтрокаБлокировки;
КонецФункции

Разбор по шагам

  1. Проверить имя учебной конфигурации, типы портов и реквизитов до COM. Порты целые в диапазоне 1..65535; секреты не сериализуются.

  2. ConnectAgent обращается только к 127.0.0.1. ConnectionString должна совпасть с построенной строкой без паролей. COM AuthenticateAgent принимает имя, пароль, в отличие от русскоязычного API ras.

  3. Выбрать УчебныйКластер85 по точному имени, локальному хосту и порту менеджера. Отсутствие или неоднозначность не заменяются выбором первого элемента.

  4. Проверить краткое описание УчебнаяБаза85 и точный маркер. Каталог живых локальных процессов позволяет взять настоящий порт|PID, а не подставить 1545 или придуманный PID.

  5. ConnectWorkingProcess использует найденный динамический порт процесса, не порт агента или ras. До аутентификации базы читаются только Name и Descr.

  6. AddAuthentication принимает только имя администратора базы и пароль, не дополнительный аргумент с именем базы. После него заново выбрать свою базу; полные поля читаются только далее.

  7. В конце показать явно перечисленные скалярные поля JSON. После успеха или ошибки очищаются все три пароля и снимается флаг Занято.

  8. GetSessions получает реальную коллекцию кластера. До чтения блокировок каждого объекта выбрать только свою базу по имени/маркеру.

  9. Сохранить SessionID как номер сеанса, а в GetSessionLocks передать сам УчебныйСеанс.

  10. Connection у сеанса может быть Неопределено. Это не основание пропустить сеанс или подставить ему любой клиентский ConnID.

  11. Проверить свои связи у каждой блокировки через полный вспомогательный код. Не обращаться к Session.InfoBase без проверки наличия Session.

  12. Показать количество блокировок отдельно для каждого сеанса. Нулевые списки не подменяются вымышленными учебными строками.

  13. При смене сеансов снимки могут отличаться. Урок не вызывает TerminateSession и не освобождает блокировку.

Как проверить результат

  1. В GetSessionLocks передан исходный объект из GetSessions, не SessionID и не Connection.

  2. Сеанс без активного соединения показан с ЕстьАктивноеСоединение=Ложь, чтение источников защищено.

  3. Опубликованные строки блокировок подтвердили собственную базу. Результат не выдается за полный отчёт СУБД.

Ожидаемый результат

На настоящих сеансах показана корректная связь с блокировками без смешивания типов и идентификаторов.

На что обратить внимание

  1. COM здесь работает в серверном Windows-процессе. Loopback означает эту машину, не компьютер тонкого клиента; Linux и незарегистрированный соединитель этому уроку не соответствуют.

  2. Присутствие учебных имён и маркера не заменяет права доступа. Не запускайте в рабочем кластере; отделите стенд от production.

  3. Порт агента, порт менеджера кластера, порт ras и динамический порт рабочего процесса — разные значения.

  4. COMSafeArray перечисляется циклом Для Каждого. Это не Массив 1С и не список UUID ras; не приписывайте ему методы или свойства другой коллекции.

  5. Снимки и выбранные процессы могут устареть между запросами. После перезапуска повторите каталог; не пытайтесь автоматически завершить мешающий процесс.

  6. Сырые COM-ошибки могут раскрывать чувствительные сведения. Разбирайте подготовку в отладчике своего стенда, не добавляйте ОписаниеОшибки в публичный JSON.

  7. SessionID уникален среди сеансов конкретной базы. Нельзя искать его во всех базах без подтверждения InfoBase.

  8. Сеанс и соединение имеют разные жизненные циклы, отсутствие Connection не означает отсутствие сеанса.

  9. Краткие объектные блокировки не заменяют технологический журнал и диагностику СУБД.

Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.