Определяем контекст сеанса 1С программно (Тонкий/Толстый клиенты/HTTP-Сервис/Фоновое задание и т.д.)

Публикация № 697624

Программирование - Практика программирования

контекст режим запуска HTTP-Сервисы

30
Иногда возникает необходимость программно определить контекст сеанса в 1С. Скажем вам надо понять что этот сеанс запущен и используется HTTP-Сервисом и не регламентным заданием или толстым клиентом. Порывшись в интернете я нашел только два способа которые не позволяли отличить регламентное задание от HTTP-Сервиса, стандартная функция ТекущийРежимЗапуска() тоже не позволяет определить запуск HTTP-Сервиса. Но в 1С есть стандартные средства которые позволяют решить эту задачу.

Конфигуратор в режиме отладки позволяет выбрать предмет отладки (Тонкий/Толстый клиенты/HTTP-Сервис/Фоновое задание и т.д.), консоль кластера также отображает тип подключения сеанса (колонка "приложение"), ну и наконец стандартная обработка "Активные пользователи" также умеет это делать.

Контекст сеанса 1С хранит в параметре ИмяПриложения соединениий с информационной базой, для того чтобы получить список сеансов текущей информационной базы можно воспользоваться фунцией ПолучитьСеансыИнформационнойБазы(), а номер текущего соединения  - НомерСоединенияИнформационнойБазы().

Для простоты и удобства пример функции, которая получает контекст сеанса:

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

 

Вызвать функцию можно так:

НомерСоединения  = НомерСоединенияИнформационнойБазы();
ИмяПриложения	 = ПолучитьИмяПриложенияТекущегоСоединения(НомерСоединения);

 

Реализация, найденная в интернете и не решающая задачу:

Функция ОпределитьКонтекст() Экспорт
    
    
 #Если ВнешнееСоединение Тогда

  Возврат "Внешнее соединение";
 #КонецЕсли

 
// Клиентов много.
#Если Клиент Тогда 
  #Если МобильноеПриложениеКлиент Тогда 
   Возврат "Мобильное приложение (клиент)";
  #КонецЕсли

  #Если ВебКлиент Тогда

   Возврат "Веб-клиент"; 
  #КонецЕсли

  #Если ТонкийКлиент Тогда

   Возврат "Тонкий клиент";
  #КонецЕсли

  #Если ТолстыйКлиентУправляемоеПриложение Тогда

   Возврат "Толстый клиент (управляемоеПриложение)";
  #КонецЕсли

  #Если ТолстыйКлиентОбычноеПриложение Тогда

   Возврат "Толстый клиент (обычноеПриложение)";
  #КонецЕсли

 #КонецЕсли

#Если Сервер Тогда 
  #Если МобильноеПриложениеСервер Тогда 
   Возврат "Мобильное приложение (сервер)";
  #КонецЕсли

  // Так как 1С:Предприятие поддерживает два варианта работы (файловый и клиент-серверный),

  // то отработаем каждый из вариантов.

  Если Лев(СтрокаСоединенияИнформационнойБазы(), 4) = "File" Тогда
  // Виртуальный сервер используется в файловом варианте.

   Возврат "Виртуальный сервер"
  Иначе
  // Реальный сервер используется в клиент-серверном варианте.

   Возврат "Реальный сервер";
  КонецЕсли;
 #КонецЕсли

 
КонецФункции

 

30

См. также

Специальные предложения

Комментарии
Избранное Подписка Сортировка: Древо
1. kuzev 40 08.11.17 15:06 Сейчас в теме
Исправьте: НомерСоеденения, ПолучитьИмяПриложенияТекущегоСоеденения.
2. azubar 37 08.11.17 15:14 Сейчас в теме
3. guy_septimiy 10.11.17 12:02 Сейчас в теме
Кажется, что предложенное решение тоже не до конца справляется.
Например для толстого клиента оно так и не ответит на вопрос - где же я нахожусь. На сервере толстого клиента, или на клиенте.
Но с оговорками да.. вполне себе вариант.
4. azubar 37 10.11.17 14:49 Сейчас в теме
(3) тут уже надо комбинировать с решением приведенным ниже:
#Если Сервер Тогда
#КонецЕсли
5. Darklight 17 13.11.17 13:57 Сейчас в теме
(3)Почему не скажет? Скажет. Проблема только с файловой базой и толстым клиентом. Но.... в этом случае "Серверного контекста" НЕ СУЩЕСТВУЕТ - все вызовы идут только под контекстом "Толстого клиента" (под обычным или управляемым приложением), даже, если в указан переход в контекст сервера (например через общи модуль с вызовом сервера) - контекст останется "Толстый клиент". А зачем Вам иное - ведь - реально контекст именно и будет "Толстый клиент" - никакого серверного контекста ВООБЩЕ не будет - будет доступно всё то, что доступно толстому клиенту - т.е. ВСЁ! В отладчике контекст будет "Толстый клиент". Более того, в толстом клиенте игнорируется не только директива "Вызов сервера", но и директива "Сервер" - т.е. будут доступны и функции чисто серверных модулей - прямо с клиента. Так устроена платформа. Вот, для тонкого клиента в файловой базе - контексты уже будут разделены.
А для толстого клиента остаётся только проверить, что он толстый клиент и это файловая база. Это можно проверить ещё и так

#Если Клиент и Сервер Тогда
    возврат "Файловый толстый клиент";
#КонецЕсли;


Аналогично толстому клиенту, в файловой базе, ведёт себя и внешнее соединение (только вместо директивы "Клиент" отрабатывает директива "ВнешнееСоединение ", а директива "Сервер" по-прежнему отрабатывает, вернее игнорируется - серверный контекст полностью доступен в контексте внешнего соединения без "вызова сервера"). Разве что интерфейсные вызовы не доступны (доступно всё то, что доступно для внешнего соединения).

#Если ВнешнееСоединение и Сервер Тогда
    возврат "Файловое внешнее соединение";
#КонецЕсли;
6. Darklight 17 13.11.17 14:11 Сейчас в теме
А ещё, для получения текущего сеанса и его приложения с релиза платформы 8.3.7 можно использовать функцию ПолучитьТекущийСеансИнформационнойБазы()

Функция ПолучитьИмяПриложенияСеанса(Представление = Ложь)
    Если Представление Тогда
	 ИмяПриложения = ПредставлениеПриложения(ПолучитьТекущийСеансИнформационнойБазы().ИмяПриложения); 
    Иначе
	 ИмяПриложения = ПолучитьТекущийСеансИнформационнойБазы().ИмяПриложения;
   КонецЕсли
КонецФункции


ну или просто сразу обращаться к ПолучитьТекущийСеансИнформационнойБазы().ИмяПриложения без дополнительных функций
triviumfan; azubar; +2 Ответить
7. 🅵🅾️🆇 14.11.17 13:44 Сейчас в теме
Предлагаю добавить в цикл при удовлетворении условию: "Прервать;".
После комментариев - пробелы.

Да и можно заменить:
Если Представление Тогда
	ИмяПриложения = ПредставлениеПриложения(Сеанс.ИмяПриложения); 
Иначе
	ИмяПриложения = Сеанс.ИмяПриложения;
КонецЕсли;

на это:
 Возврат ?(Представление, ПредставлениеПриложения(Сеанс.ИмяПриложения), Сеанс.ИмяПриложения);

Тогда и "Прервать;" не нужно)))

Комментарии перед функцией лучше оформить следующим образом (тогда при вводе будут подсказки о параметрах):
// ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~
//						Yandex speller 
// ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~
// Проверка орфографии средствами Yandex speller через HTTP GET
// https://tech.yandex.ru/speller/doc/dg/concepts/speller-overview-docpage/
//
// Функция возвращает структуру со следующими парами Ключ-Значение:
//	БезОшибок, КоличествоОшибок, ИсходныйТекст, ИсправленныйТекст, ШаблонТекста, Ошибки
//	БезОшибок (булево)			- Текст не содержит/содержит ошибки.
//	КоличествоОшибок (число)	- Количество ошибок в тексте
//	ИсходныйТекст (строка)		- Текст переданый в функцию
//	ИсправленныйТекст (строка)	- Текст с исправленными ошибками (ошибки заменены на первую подсказку)
//	ШаблонТекста				- Текст в котором места ошибок обрамлены в "ИндексОшибки" 
//	Ошибки (массив структур)	- Состоит из КодОшибки (число), 
//									ОписаниеОшибки (строка), ПозицияСлова (число), НомерСтроки (число), 
//									НомерСтолбца (число), ДлинаСлова (число), Подсказки (массив строк) 
// В случае неудачи функция возвращает "Неопределено" и выводит сообщение об ошибке.
//
// Параметры:
//	Текст						- [обязательный](строка)
//								параметром передается текст на проверку
//	Язык						- [необязательный](строка)
//								Языки проверки (перечисляются через запятую).
//								Возможные значения:
//									ru – русский;
//									uk – украинский;
//									en – английский.
//								По умолчанию: "ru,en".
//	Опции						- [необязательный](число)
//								Опции Яндекс.Спеллера.
//								Значением параметра является сумма значений требуемых опций,
//								см. https://tech.yandex.ru/speller/doc/dg/reference/speller-options-docpage/
//								Например, Опции = 5 - это сумма опций IGNORE_UPPERCASE и IGNORE_URLS.
//								По умолчанию Опции = 31 (IGNORE_UPPERCASE, IGNORE_DIGITS, IGNORE_URLS, FIND_REPEAT_WORDS, IGNORE_LATIN).								
//	Формат						- [необязательный](строка)
//								Формат проверяемого текста.
//								Возможные значения:
//									plain - текст без разметки (значение по умолчанию)
//								    html - HTML-текст.
//	ИсправлятьИсходныйТекст		- [необязательный](булево) 
//								если Истина, то исходный текст исправляется
//								может быть полезно, если использовать как процедуру и возвращать первый параметр "Текст".
//								По умолчанию Ложь.
//	СообщатьОбОшибках			- [необязательный](булево) 
//								если Истина (значение по умолчанию), то будут выводиться сообщения об ошибках
//	Словарь						- [необязательный](строка) 
//								если заданы метаданные словаря (вида: "Справочник.Словарь"), 
//								то будут исключаться из ошибочных слова содержащиеся в наименованиях справочника "Словарь".
//								Если передана строка с разделителями ";", 
//								то вместо справочника словаря будет использоваться она.
//								По умолчанию пустая строка.
//	МинДлинаСлова				- [необязательный](число) 
//								минимальная длина слова подлежащего проверке
//								По умолчанию 0 (проверять все слова).
Показать



Идеалистических побуждений, а не критики ради :3
HomeInc; azubar; +2 Ответить
8. yur4ik9408 33 24.11.17 15:02 Сейчас в теме
как программа отреагирует на такую конструкцию:
Контекст = "";
Выполнить("Контекст = ОпределитьКонтекст();");
Сообщить("Контекст");
9. azubar 37 25.11.17 06:45 Сейчас в теме
(8) Нормально, только Сообщить("Контекст"); выводит строку "Контекст", надо так: Сообщить(Контекст);
Оставьте свое сообщение