При разработке мобильных решений на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с необходимостью адаптации интерфейса и логики системы под конкретный тип устройства. Одной из самых сложных задач в этом контексте является определение типа клиента (мобильный клиент, мобильное приложение или тонкий клиент) на самом раннем этапе запуска системы — в модуле сеанса. Это критично, когда нам нужно программно настроить состав начальной страницы или рабочие столы пользователя до того, как интерфейс будет отрисован на устройстве.
В этой статье мы подробно разберем, почему стандартные директивы компиляции не подходят для этой задачи и как правильно использовать механизмы платформы для получения точной информации о типе подключения на стороне сервера.
Рассмотрим стандартную ситуацию. Многие разработчики пытаются использовать привычные директивы, такие как #Если МобильныйКлиент или #Если МобильноеПриложениеКлиент. Однако важно понимать жизненный цикл запуска приложения. Процедура УстановкаПараметровСеанса в модуле сеанса выполняется исключительно на сервере. Директивы, ориентированные на клиентскую часть, в этом контексте всегда будут возвращать Ложь, так как сервер «не знает», какой именно клиент инициировал запрос, используя только средства препроцессора.
События при запуске системы происходят в следующей последовательности:
УстановкаПараметровСеанса в модуле сеанса (Сервер).ПередНачаломРаботыСистемы и ПриНачалеРаботыСистемы (Клиент).Как мы видим, к моменту срабатывания клиентских событий, где мы могли бы легко определить тип клиента, настройки начальной страницы уже загружены из хранилища системных настроек. Следовательно, нам нужно найти способ «перехватить» информацию о клиенте на шаге №2.
Единственным надежным способом определить тип клиента на сервере в модуле сеанса является использование объекта сеанса информационной базы. Платформа 1С сохраняет информацию о приложении, через которое произведено подключение, в свойствах сеанса. Разберем по шагам, как это реализовать.
Проанализируем свойство ИмяПриложения. Для этого нам понадобится метод ПолучитьТекущийСеансИнформационнойБазы(). Рассмотрим пример кода, который необходимо разместить в обработчике УстановкаПараметровСеанса:
Процедура УстановкаПараметровСеанса(ТребуемыеПараметры)
ТекущийСеанс = ПолучитьТекущийСеансИнформационнойБазы();
ИмяПриложения = ТекущийСеанс.ИмяПриложения;
// Определяем, является ли клиент мобильным
ЭтоМобильныйКлиент = (ИмяПриложения = "MobileClient");
ЭтоМобильноеПриложение = (ИмяПриложения = "MobileAppClient");
Если ЭтоМобильныйКлиент Тогда
// Здесь можно установить специфические параметры сеанса
// или подменить настройки рабочего стола в хранилище настроек
ПараметрыСеанса.ТипКлиентаДляНастроек = "Мобильный";
Иначе
ПараметрыСеанса.ТипКлиентаДляНастроек = "Десктоп";
КонецЕсли;
КонецПроцедуры
В данном примере мы получаем строку-идентификатор приложения. Платформа использует следующие основные значения для свойства ИмяПриложения:
Иногда требуется отличить мобильный клиент от мобильного браузера (веб-клиента на смартфоне). В этом случае одного ИмяПриложения может быть недостаточно, так как для браузера оно всегда будет WebClient. Если ваша задача требует более глубокого анализа, можно попытаться проанализировать строку UserAgent, однако в модуле сеанса прямой доступ к заголовкам HTTP-запроса ограничен. Поэтому для базовой идентификации мобильного клиента 1С вышеописанный метод с ИмяПриложения является эталонным и наиболее производительным.
Выясним, как использовать полученную информацию для решения задачи автора — изменения рабочего стола. Поскольку настройки начальной страницы считываются платформой автоматически, мы можем программно повлиять на них в УстановкаПараметровСеанса, записывая нужные значения в ХранилищеСистемныхНастроек непосредственно перед тем, как платформа их запросит.
Рассмотрим пример реализации такой логики:
Процедура УстановкаПараметровСеанса(ТребуемыеПараметры)
Сеанс = ПолучитьТекущийСеансИнформационнойБазы();
Если Сеанс.ИмяПриложения = "MobileClient" Тогда
// Устанавливаем признак в параметрах сеанса для дальнейшего использования в коде
ПараметрыСеанса.ЭтоМобильноеУстройство = Истина;
// Читаем из справочника Пользователи настройки для мобильного интерфейса
// И записываем их в системное хранилище для текущего пользователя
НастройкиМК = ПолучитьНастройкиРабочегоСтолаДляМобильногоКлиента(Пользователи.ТекущийПользователь());
ХранилищеСистемныхНастроек.Сохранить("Общее/НастройкиНачальнойСтраницы", "", НастройкиМК);
КонецЕсли;
КонецПроцедуры
Важный момент: помните, что чрезмерное использование записи в хранилище настроек при каждом входе может создать нагрузку на базу данных. Рекомендуется сначала проверить, не установлены ли уже нужные настройки, и выполнять запись только при необходимости смены контекста (например, если пользователь зашел с компьютера после работы на телефоне).
Проанализируем ситуацию с мобильным клиентом, поддерживающим автономный режим. В этом случае, когда устройство теряет связь с основным сервером, код начинает выполняться локально на мобильной платформе. В такой ситуации в модуле сеанса на стороне мобильного устройства сработает директива #Если МобильноеПриложениеСервер. Это позволяет разделять логику даже внутри серверных процедур модуля сеанса, если конфигурация подразумевает гибридную работу.
Подведем итог нашему исследованию. Для того чтобы успешно определить мобильный клиент в модуле сеанса, следует придерживаться следующих правил:
#Если Клиент, #Если МобильныйКлиент), так как они не работают на сервере.ИнформационнаяБазаСеанс и его свойство ИмяПриложения."MobileClient".ПараметрыСеанса.ЭтоМобильныйКлиент), чтобы в дальнейшем не вызывать ресурсоемкий метод ПолучитьТекущийСеансИнформационнойБазы() в других частях кода.Использование этого подхода гарантирует, что ваша система будет корректно определять тип устройства в самый первый момент инициализации, позволяя гибко управлять интерфейсом и функциональностью приложения в зависимости от среды исполнения.