IE2017

Запрет запуска нескольких сеансов

Администрирование - Системное

Запрет запуска нескольких сеансов
Пользователь запустил несколько сеансов 1с и параллельно формирует отчеты, в результате чего повесил сервак?

 

Шёл тихий, спокойный рабочий день, ничего не предвещало беды. 

Но, закон подлости подкрался незаметно. Повис терминальный сервак(Да, сервак не слишком то мощный, но всё же...).

Появилась задача запретить запуск нескольких сеансов 1с, дабы наши доблестные юзера не могли разом формировать много-много больших отчётиков.

 

Задачка, вроде бы простая, но естетственно у юзеров нет права на просмотр списка активных пользователей. Поиски в интеренете не дали никаких результатов, ибо предлагалось много чего, начиная от раздачи всем прав на просмотр списка активных пользователей, заканчивая COM соединением с той же базой.

После недолгих раздумий родилось следующее:

1) в любом привелигированном модуле(в моём случае модуль называется ПолныеПрава) добавлем функцию:

Функция ПолучитьСписокАктивныхПользователей() Экспорт
	СписокАктивныхЮзеров=ПолучитьСоединенияИнформационнойБазы();
	Запрос=Новый Запрос;
	Запрос.Текст="ВЫБРАТЬ
	|	""                                                                   "" КАК Пользователь,
	|	""                                                                   "" КАК ИмяКомпьютера";
	ТЗ=Запрос.Выполнить().Выгрузить().СкопироватьКолонки();
	для Каждого ЭлементМассива из СписокАктивныхЮзеров Цикл
		если ЭлементМассива.ИмяПриложения="1CV8" тогда
			НоваяСтрока=ТЗ.Добавить();
			НоваяСтрока.Пользователь=ВРег(СокрЛП(ЭлементМассива.Пользователь.Имя));
			НоваяСтрока.ИмяКомпьютера=ВРег(СокрЛП(ЭлементМассива.ИмяКомпьютера));
		КонецЕсли;
	КонецЦикла;
	Возврат ТЗ;
КонецФункции

сделать напрямую Возврат ПолучитьСоединенияИнформационнойБазы(); нельзя ибо 1с запустится с ошибкой "Передача мутабельного значения...."

2) В модуле приложения в процедуре ПриНачалеРаботыСистемы() пишем следующее:

	Если Не РольДоступна("ПолныеПрава") Тогда
		НеРазрешатьПодключение=Ложь;
		ИмяКомпа=ИмяКомпьютера();
		АктивныеПользователи=ПолныеПрава.ПолучитьСписокАктивныхПользователей();
		мЮзер=ВРег(СокрЛП(ПараметрыСеанса.ТекущийПользователь.Код));
		КолСеанс=0;
		Для каждого АктивныйПользователь Из АктивныеПользователи Цикл
			Если АктивныйПользователь.Пользователь=мЮзер Тогда
				Если АктивныйПользователь.ИмяКомпьютера=ИмяКомпа Тогда
					КолСеанс=КолСеанс+1;
					Если КолСеанс=2 Тогда
						Предупреждение("Под пользователем "+Строка(АктивныйПользователь.Пользователь)+" на компьютере "+АктивныйПользователь.ИмяКомпьютера+" уже имеется соединение."+Символы.ПС+"Работа системы будет завершена.");
						НеРазрешатьПодключение=Истина;
						Прервать;
					КонецЕсли;
				КонецЕсли;
			КонецЕсли;
		КонецЦикла;
		Если НеРазрешатьПодключение Тогда
			ЗавершитьРаботуСистемы(Ложь);
		КонецЕсли;
	КонецЕсли;

Как результат мы получили "Profit" все рады, все довольны)

См. также

Комментарии
1. Петр (peterxx) 15 18.10.13 11:14 Сейчас в теме
А все ли? Теперь пользователи не могут параллельно формировать много, много разных отчетиков... )
2. Векославъ Русъ (inclodes) 11 18.10.13 11:22 Сейчас в теме
(1) peterxx, чего-то я совершенно не понял о чём вы.
3. andrey dyak (dyak84) 18.10.13 13:16 Сейчас в теме
Автор считаю статю не совсем полной а что делать если у пользователя не полные права а работать нужно в 2 сеансах. Давать полные права тогда он может натворить того что не нужно. а что делать если вирубался свет, зайти то в 1С ты тоже не можеш сеанс то висит. Думаю хорошо было б зделать на подобие
ЗапретитьОткрытиеНесколькихСеансов = УправлениеПользователями.ПолучитьЗначениеПоУмолчанию(глЗначениеПеременной("глТекущийПользователь"), "ЗапретитьОткрытиеНесколькихСеансов");
Если ЗапретитьОткрытиеНесколькихСеансов Тогда
ТекущийНомерСоединения = НомерСоединенияИнформационнойБазы();
УникальныйИдентификаторПользователя = ПользователиИнформационнойБазы.ТекущийПользователь().УникальныйИдентификатор;

МассивСоединений = ПолучитьСоединенияИнформационнойБазы();
Для Каждого ТекСоединение Из МассивСоединений Цикл
Если (ТекСоединение.ИмяПриложения = "1CV8")
И (НЕ ТекСоединение.НомерСоединения = ТекущийНомерСоединения)
И (НЕ ТекСоединение.Пользователь = неопределено)
И (ТекСоединение.Пользователь.УникальныйИдентификатор = УникальныйИдентификаторПользователя) Тогда

Предупреждение("Пользователем с таким именем уже выполнен вход в систему");
ЗавершитьРаботуСистемы(Ложь);
Возврат;

КонецЕсли;
КонецЦикла;
КонецЕсли;
и завести дополнительное право на работу с несколькими сеансами. И какам то образом проверять время бездействия пользователя.
Andreyyy; pandanation; baton_pk; +3 Ответить
4. kiv82 (AltF1) 21.10.13 08:09 Сейчас в теме
В УПП есть такая настройка пользователя.
5. Андрей Акулов (DrAku1a) 1204 23.10.13 03:17 Сейчас в теме
(4) и в УТ и в КА, по-моему эта настройка у 1С уже давно в стандартных решениях. Может даже и в БСП есть. Так что автора можно поздравить - он изобрёл велосипед.
6. DAnry (DAnry) 12 23.10.13 13:18 Сейчас в теме
Запрет запуска нескольких сеансов бывает полезным... Но, как говорится, всему свое время. Такую вещь опционально надо делать. Надо включил, не надо - выключил. Но может статься и "нежданчик"
7. Елена К (Ele1234567) 11.04.14 14:36 Сейчас в теме
Нужно будет попробовать.
8. Иван Иваныч (dima_home) 14 20.12.16 12:15 Сейчас в теме
Процедуры автора не работают на клиент серверной системе с управляемыми формами.
из-за передачи мутабельных значений.
Переделал
В привилегированном модуле (у нас это "_ПодключениеКом")

Функция ПолучитьСписокАктивныхПользователей() Экспорт
    СписокАктивныхЮзеров=ПолучитьСоединенияИнформационнойБазы();
          //Таблицу значений нельзя использовать, т.к. ее не передать с сервера на клиент
	МассивПользователей =новый Массив();
    для Каждого ЭлементМассива из СписокАктивныхЮзеров Цикл
		если ЛЕВ(ЭлементМассива.ИмяПриложения,4)="1CV8" тогда
			МассивПользователей.Добавить(Новый Структура("Пользователь,ИмяКомпьютера",ВРег(СокрЛП(ЭлементМассива.Пользователь.Имя)),ВРег(СокрЛП(ЭлементМассива.ИмяКомпьютера))));
        КонецЕсли;
    КонецЦикла;
    Возврат МассивПользователей;
КонецФункции
...Показать Скрыть


В модуле управляемого приложения:

&НаКлиенте
Процедура ПриНачалеРаботыСистемы()

 	//Если Не РольДоступна("ПолныеПрава") Тогда  //на клиенте нельзя так проверять роль.
        НеРазрешатьПодключение=Ложь;
        ИмяКомпа=ВРег(ИмяКомпьютера());  //тут автор забыл сделать верхний регистр
        АктивныеПользователи=_ПодключениеКом.ПолучитьСписокАктивныхПользователей();
        мЮзер=ВРег(СокрЛП(УправлениеПользователями.ПолучитьТекущегоПользователя()));  //Это у нас так пользователя получаем.
        //мЮзер=ВРег(СокрЛП(ПараметрыСеанса.ТекущийПользователь.Код)); //так возможно у вас надо получить.

        КолСеанс=0;
		Для ННН = 0 ПО АктивныеПользователи.ВГраница() Цикл
            Если АктивныеПользователи[ННН].Пользователь=мЮзер Тогда
                Если АктивныеПользователи[ННН].ИмяКомпьютера=ИмяКомпа Тогда
                    КолСеанс=КолСеанс+1;
                    Если КолСеанс=2 Тогда
                        Предупреждение("Под пользователем "+АктивныеПользователи[ННН].Пользователь+" на компьютере "+АктивныеПользователи[ННН].ИмяКомпьютера+" уже имеется соединение."+Символы.ПС+"Работа системы будет завершена.",30);  //Модальное окно надо делать всегда с таймаутом.
                        НеРазрешатьПодключение=Истина;
                        Прервать;
                    КонецЕсли;
                КонецЕсли;
            КонецЕсли;
        КонецЦикла;
        Если НеРазрешатьПодключение Тогда
            ЗавершитьРаботуСистемы(Ложь);
        КонецЕсли;
   // КонецЕсли;
КонецПроцедуры
  
//100% рабочее.
...Показать Скрыть
Оставьте свое сообщение