Как определить, что пользователь вошел в 1С через Мобильный Клиент?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Разбираемся в понятиях: Мобильное Приложение и Мобильный Клиент

Прежде чем переходить к методам определения, критически важно понять разницу между Мобильным Приложением и Мобильным Клиентом в экосистеме 1С:Предприятия. Это два разных способа работы с мобильными устройствами, и для их идентификации используются разные подходы.

  1. Мобильное Приложение (Mobile Application)

    Это автономное приложение, которое устанавливается непосредственно на мобильное устройство пользователя (например, смартфон или планшет). Ключевые особенности:

    • Оно содержит собственную файловую информационную базу, которая находится на мобильном устройстве.
    • Может работать полностью офлайн, без постоянного подключения к основной базе 1С.
    • Для обмена данными с центральной базой требуется явная настройка синхронизации, что подразумевает более сложную логику обмена.
    • Разработка и распространение такого приложения могут быть более трудоемкими, так как каждое изменение часто требует перепубликации в магазинах приложений (AppStore, Google Play).
    • Для работы мобильного приложения не требуются клиентские лицензии 1С, так как отсутствует прямое клиент-серверное взаимодействие с основной базой.
  2. Мобильный Клиент (Mobile Client)

    Этот вариант является аналогом тонкого клиента 1С, но специально адаптированным для работы на мобильных устройствах. Он предоставляет онлайн-доступ к основной информационной базе 1С, опубликованной на веб-сервере. Основные характеристики:

    • Предоставляет онлайн-доступ к центральной информационной базе.
    • Данные не хранятся постоянно на мобильном устройстве, а доступны в режиме реального времени, как при работе с тонким или веб-клиентом.
    • Интерфейс обычных форм 1С адаптируется для удобной работы на маленьких экранах мобильных устройств.
    • Для работы мобильного клиента требуются клиентские лицензии 1С, аналогично обычным тонким клиентам.
    • Существует также Мобильный клиент с автономным режимом, который позволяет работать офлайн, а при восстановлении соединения синхронизировать данные с серверной базой. Это гибридный вариант, сочетающий черты мобильного клиента и мобильного приложения.

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

Использование директив препроцессора для определения типа клиента

Для определения типа клиентского приложения на этапе компиляции кода 1С мы можем использовать специальные директивы препроцессора. Эти директивы позволяют включить или исключить блоки кода в зависимости от того, для какого клиентского приложения компилируется модуль.

Рассмотрим две ключевые директивы, которые помогут нам в нашей задаче:

  1. Директива #Если МобильноеПриложениеКлиент Тогда ... #КонецЕсли

    Эта директива позволяет нам включить код, который будет выполняться только в том случае, если текущий модуль компилируется для мобильного приложения на стороне клиента. Она очень полезна для специфичной логики, присущей автономным мобильным приложениям.

    Посмотрим на пример использования:

    
    #Если МобильноеПриложениеКлиент Тогда
        Сообщить("Обнаружен запуск в автономном Мобильном Приложении!");
        // Здесь может быть специфичный код для работы с локальной базой или офлайн-режимом
        НастройкаОбменаДанными();
    #КонецЕсли;
    

    Этот код будет скомпилирован и исполнен только тогда, когда приложение запущено именно как Мобильное Приложение.

  2. Директива #Если МобильныйКлиент Тогда ... #КонецЕсли

    Несмотря на некоторые первоначальные сомнения в сообщении на форуме, эта директива действительно существует и предназначена для кода, специфичного для мобильного клиента. Она позволяет нам выделить логику, которая должна выполняться, когда пользователь работает с основной информационной базой через мобильный клиент (по аналогии с тонким клиентом).

    Разберем пример:

    
    #Если МобильныйКлиент Тогда
        Сообщить("Обнаружен запуск через Мобильный Клиент!");
        // Здесь может быть код, специфичный для онлайн-доступа через мобильное устройство
        АдаптироватьИнтерфейсПодМобильныйКлиент();
    #КонецЕсли;
    

    Этот блок кода будет активен только при компиляции для Мобильного Клиента.

Мы можем объединить эти директивы для более гибкого определения типа клиента, как было предложено в одном из сообщений форума:


#Если МобильноеПриложениеКлиент Тогда
    Приложение = НСтр("ru = 'мобильное приложение'");
#ИначеЕсли МобильныйКлиент Тогда
    Приложение = НСтр("ru = 'мобильный клиент'");
#Иначе
    // Если ни одно из вышеперечисленных условий не выполнилось,
    // это может быть тонкий клиент, веб-клиент или толстый клиент.
    #Если ТонкийКлиент Тогда
        Приложение = НСтр("ru = 'тонкий клиент'");
    #ИначеЕсли ВебКлиент Тогда
        Приложение = НСтр("ru = 'веб-клиент'");
    #ИначеЕсли ТолстыйКлиент Тогда
        Приложение = НСтр("ru = 'толстый клиент'");
    #Иначе
        Приложение = НСтр("ru = 'неизвестный клиент'");
    #КонецЕсли;
#КонецЕсли;
Сообщить("Приложение запущено как: " + Приложение);

Где можно использовать директивы препроцессора?

Инструкции препроцессора обрабатываются на этапе компиляции кода и глобально определяют, для какой сборки будет исполняться код. Их можно успешно применять в следующих клиентских модулях:

Важно понимать: эти директивы работают на стороне клиента и определяют среду, в которой компилируется и исполняется клиентский код.

Определение типа клиента в серверных модулях и модуле сеанса

Возникает вопрос: а что если нам нужно определить тип клиента на стороне сервера, например, в модуле сеанса (МодульСеанса) или в серверном общем модуле? Директивы препроцессора, рассмотренные выше, не могут быть использованы напрямую на сервере для определения типа клиента в момент старта сеанса, как верно подметил участник форума. Серверный код не "знает" о клиентской среде в момент своей компиляции и исполнения. Сеанс может быть запущен даже без участия клиента (например, фоновое задание, COM-соединение).

Для программного определения контекста сеанса на стороне сервера мы можем использовать несколько подходов:

  1. Способ 1: Передача информации с клиента на сервер

    Этот подход предполагает, что клиентское приложение самостоятельно определяет свой тип с помощью директив препроцессора, а затем передает эту информацию на сервер. Сервер может сохранить эту информацию, например, в параметрах сеанса.

    Разберем по шагам, как это можно реализовать:

    1. На стороне клиента (например, в модуле управляемого приложения):

      В обработчике события ПриНачалеРаботыСистемы() или подобном, мы определяем тип клиента и устанавливаем соответствующий параметр сеанса.

      
      // МодульУправляемогоПриложения - ПриНачалеРаботыСистемы()
                      
      #Если МобильныйКлиент Тогда
          УстановитьПараметрСеанса("ТипКлиента", "МобильныйКлиент");
      #ИначеЕсли МобильноеПриложениеКлиент Тогда
          УстановитьПараметрСеанса("ТипКлиента", "МобильноеПриложение");
      #Иначе
          // Для других типов клиентов (тонкий, веб, толстый)
          #Если ТонкийКлиент Тогда
              УстановитьПараметрСеанса("ТипКлиента", "ТонкийКлиент");
          #ИначеЕсли ВебКлиент Тогда
              УстановитьПараметрСеанса("ТипКлиента", "ВебКлиент");
          #ИначеЕсли ТолстыйКлиент Тогда
              УстановитьПараметрСеанса("ТипКлиента", "ТолстыйКлиент");
          #Иначе
              УстановитьПараметрСеанса("ТипКлиента", "НеизвестныйКлиент");
          #КонецЕсли;
      #КонецЕсли;
                      
      // Пример функции УстановитьПараметрСеанса (должна быть реализована на сервере)
      // Пример: ОбщийМодульСервер.УстановитьПараметрСеанса(ИмяПараметра, Значение)
      Процедура УстановитьПараметрСеанса(ИмяПараметра, Значение) Экспорт
          // Вызов серверной функции для установки параметра сеанса
          ОбщийМодульСервер.УстановитьПараметрСеансаНаСервере(ИмяПараметра, Значение);
      КонецПроцедуры
      

      И, соответственно, на сервере (например, в ОбщемМодуле с галочкой "Сервер"):

      
      // ОбщийМодульСервер - Сервер
      Процедура УстановитьПараметрСеансаНаСервере(ИмяПараметра, Значение) Экспорт
          ПараметрыСеанса[ИмяПараметра] = Значение;
      КонецПроцедуры
      
    2. На стороне сервера (в модуле сеанса или любом серверном модуле):

      После установки параметра сеанса на клиенте, мы можем получить его значение на сервере.

      
      // МодульСеанса - ПриНачалеСеанса()
      Функция ПриНачалеСеанса()
          // ... ваш код инициализации сеанса ...
                      
          Если ПараметрыСеанса.Свойство("ТипКлиента") Тогда
              ТипКлиента = ПараметрыСеанса.ТипКлиента;
              Если ТипКлиента = "МобильныйКлиент" Тогда
                  Сообщить("Пользователь подключился через Мобильный Клиент. Выполняем специфические действия...");
                  // Например, можно записать в журнал регистрации, установить специфические настройки
                  ЗаписатьВЖурналРегистрации("МобильныйКлиент", ТипКлиента);
              ИначеЕсли ТипКлиента = "МобильноеПриложение" Тогда
                  Сообщить("Пользователь подключился через Мобильное Приложение.");
              КонецЕсли;
          Иначе
              // Обработка случаев, когда параметр еще не установлен (например, для фоновых заданий)
              Сообщить("Не удалось определить тип клиента из параметров сеанса.");
          КонецЕсли;
                      
          // ... продолжение вашего кода ...
      КонецФункции
      

      Этот способ является достаточно надежным, так как информация передается явно от клиента.

  2. Способ 2: Использование функции РежимЗапускаКлиентскогоПриложения()

    Функция РежимЗапускаКлиентскогоПриложения() является наиболее прямым и рекомендуемым способом определения режима запуска клиентского приложения текущего сеанса работы. Она доступна как на тонком клиенте, веб-клиенте, так и на сервере, толстом клиенте и внешнем соединении, что делает ее очень универсальной.

    Посмотрим на ее применение:

    
    // Доступно как на клиенте, так и на сервере
            
    РежимЗапуска = РежимЗапускаКлиентскогоПриложения();
            
    Если РежимЗапуска = РежимЗапускаКлиентскогоПриложения.МобильныйКлиент Тогда
        Сообщить("Сеанс запущен в режиме Мобильного Клиента.");
        // Выполнить специфические действия для Мобильного Клиента
    ИначеЕсли РежимЗапуска = РежимЗапускаКлиентскогоПриложения.МобильноеПриложение Тогда
        Сообщить("Сеанс запущен в режиме Мобильного Приложения.");
        // Выполнить специфические действия для Мобильного Приложения
    ИначеЕсли РежимЗапуска = РежимЗапускаКлиентскогоПриложения.ТонкийКлиент Тогда
        Сообщить("Сеанс запущен в режиме Тонкого Клиента.");
    ИначеЕсли РежимЗапуска = РежимЗапускаКлиентскогоПриложения.ВебКлиент Тогда
        Сообщить("Сеанс запущен в режиме Веб-Клиента.");
    Иначе
        Сообщить("Сеанс запущен в другом режиме: " + РежимЗапуска);
    КонецЕсли;
    

    Эта функция возвращает значение из перечисления РежимЗапускаКлиентскогоПриложения. Среди возможных значений, которые нас интересуют:

    • РежимЗапускаКлиентскогоПриложения.МобильныйКлиент
    • РежимЗапускаКлиентскогоПриложения.МобильноеПриложение
    • РежимЗапускаКлиентскогоПриложения.ТонкийКлиент
    • РежимЗапускаКлиентскогоПриложения.ВебКлиент
    • РежимЗапускаКлиентскогоПриложения.ТолстыйКлиент
    • РежимЗапускаКлиентскогоПриложения.ВнешнееСоединение (для COM-соединений)
    • РежимЗапускаКлиентскогоПриложения.ФоновоеЗадание

    Использование РежимЗапускаКлиентскогоПриложения() является наиболее чистым и рекомендуемым способом, так как он предоставляет стандартизированное значение независимо от контекста вызова.

  3. Способ 3: Анализ активных сеансов с `ПолучитьСеансыИнформационнойБазы()`

    Этот способ больше подходит для административных задач или для анализа текущих подключений. Функция ПолучитьСеансыИнформационнойБазы() позволяет получить список всех активных сеансов в информационной базе. У каждого объекта сеанса есть свойство ИмяПриложения, которое может указывать на тип клиента.

    Разберем пример использования:

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

    Важно: Значения свойства ИмяПриложения могут варьироваться в зависимости от версии платформы 1С и настроек публикации. Для точного определения всегда рекомендуется проверить актуальные значения при отладке или обратиться к свежей документации 1С. Тем не менее, этот метод дает общую картину активных сеансов и может быть полезен в определенных сценариях.

Определение операционной системы мобильного устройства

Если нам необходимо определить операционную систему мобильного устройства (iOS или Android) при работе с Мобильным Клиентом или Мобильным Приложением, мы можем воспользоваться объектом СистемнаяИнформация. Этот объект предоставляет доступ к различным системным параметрам, включая информацию об операционной системе.

Посмотрим на пример, как это можно сделать:


// Этот код должен выполняться на клиентской стороне (МобильныйКлиент или МобильноеПриложение)
#Если МобильныйКлиент Или МобильноеПриложениеКлиент Тогда
    
    // Получаем версию ОС
    ИнформацияОС = СистемнаяИнформация().ВерсияОС;
    
    Если Найти(ВЕРХН(ИнформацияОС), "IOS") > 0 Тогда
        Сообщить("Клиент работает на iOS.");
    ИначеЕсли Найти(ВЕРХН(ИнформацияОС), "ANDROID") > 0 Тогда
        Сообщить("Клиент работает на Android.");
    Иначе
        Сообщить("Клиент работает на неизвестной мобильной ОС: " + ИнформацияОС);
    КонецЕсли;
    
#КонецЕсли;

Функция СистемнаяИнформация().ВерсияОС возвращает строку, содержащую информацию о версии операционной системы. Используя функции для работы со строками (например, Найти и ВЕРХН), мы можем определить, является ли ОС iOS или Android. Для расширения возможностей взаимодействия со средой Android можно применить внешнюю компоненту с набором системных утилит.

Таким образом, для точного определения того, что пользователь зашел через Мобильный Клиент или Мобильное Приложение, мы рекомендуем использовать комбинацию директив препроцессора в клиентских модулях и функцию РежимЗапускаКлиентскогоПриложения() для серверной логики. Это обеспечит гибкость и надежность вашего решения.

← На главную