[ Наглядно о непонятном ] – Как работает серверный вызов в 1С

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

Это будет полезно начинающим разработчикам и тем, у кого есть пробелы в области клиент-серверного взаимодействия – всё объясним «на пальцах» :)

Клиент-серверная архитектура заложена в платформе изначально – со времен «1С:Предприятие 8.0».

Однако при разработке на 8.0 и 8.1 о разделении кода на клиентскую и серверную часть можно было не заботиться, поскольку на клиенте (на толстом клиенте) был доступен тот же функционал, что и на сервере.

Всё изменилось с выходом платформы «1С:Предприятие 8.2», когда появился тонкий клиент. Теперь на клиенте доступен один функционал, на сервере – другой. Клиент и сервер «общаются» между собой с помощью серверного вызова.

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

Немного базовой теории

Перед тем, как перейти к содержательной части, договоримся о некоторых ограничениях:

  • Мы подразумеваем, что Вы знаете о существовании четырёх директив компиляции, доступных в модулях формы: «&НаКлиенте», «&НаСервере», «&НаСервереБезКонтекста» и «&НаКлиентеНаСервереБезКонтекста».
  • Все примеры будут опираться на работу «1С:Предприятие 8» в клиент-серверном режиме. Файловый вариант по сути является эмуляцией клиент-серверного режима, с небольшими отклонениями (для данной статьи это не критично)
  • В рамках этого материала рассматривается исключительно взаимодействие клиента и сервера 1С. Работа с базой данных, преобразование данных и прочие нюансы работы системы – это темы других статей.

Далее, освежим в памяти немного теории.

Директивы, в имени которых упоминается «Клиент», устанавливают ограничение на обращение к базе данных.

Процедуры или функции, написанные под директивой «Без контекста», не имеют доступа к контексту (данным) формы. Исходя из этой информации, легко представить ограничения директив по доступу к данным в виде следующей таблицы:

ДирективаДанные формыБаза данных
&НаКлиенте+
&НаСервере++
&НаСервереБезКонтекста+
&НаКлиентеНаСервереБезКонтекста

Опережая вопрос «Для чего же директива с самым длинным названием, если она ограничивает и использование контекста форм, и обращения к базе данных?», напомню: любая процедура и функция поддерживает обработку информации, переданной в неё в качестве параметров.

Отсюда делаем вывод: у методов, описанных под директивой «&НаКлиентеНаСервереБезКонтекста», единственным источником данных являются эти самые переданные параметры.

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

  • &НаКлиенте
  • &НаСервере
  • &НаСервереБезКонтекста
  • &НаКлиентеНаСервереБезКонтекста.

То есть из метода, описанного под директивой «&НаКлиенте», можно вызывать процедуры и функции, описанные под любой директивой. А вот «из-под» директивы «&НаСервереБезКонтекста» можно вызывать только то, что описано под директивой «&НаСервереБезКонтекста» или «&НаКлиентеНаСервереБезКонтекста».

Теперь про серверный вызов

Серверный вызов – это передача какой-то информации с клиентской части «1С:Предприятие 8» на серверную часть с целью вернуть обратно некий набор данных.

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

Рисунок 1

«Оу! При чём тут Библиотека?!» – спросите Вы.

Всё очень просто:

Рисунок 2

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

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

Но, для того чтобы перейти к основной теме данной статьи, необходимо сначала разобраться – где будет выполняться программный код, написанный под определенными директивами. То есть на какой части приложения «1С:Предприятие 8» будут доступны процедуры и функции, описанные под директивами «&НаКлиенте», «&НаСервере», «&НаСервереБезКонтекста» и «&НаКлиентеНаСервереБезКонтекста»:

Рисунок 3

Видим, что на стороне клиента у нас будут доступны процедуры и функции, написанные под двумя директивами из четырёх, а на стороне сервера – под тремя из четырёх.

Сразу возникают вопросы: «Зачем такое многообразие и чем оно полезно?», «Как метод, описанный под директивой «&НаКлиентеНаСервереБезКонтекста» может выполняться и на клиенте, и на сервере?».

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

И в этом нам помогут наши новые друзья, знакомьтесь!


Это процесс клиентской части приложения «1С:Предприятие 8». Он запускается на компьютере пользователя и сожительствует в оперативной памяти с другими процессами (38 вкладок браузера, поток аудио из социальной сети, telegram и другие). Может порождать серверный вызов.

Это процесс серверной части приложения «1С:Предприятие 8». Он существует на сервере 1С. Знает, какие клиентские сеансы в данный момент запущены, но самостоятельно не может инициировать взаимодействие с ними. Работает с клиентской частью только через полученный от неё серверный вызов.

А это серверный вызов. Как было сказано выше, он порождается процессом клиентской части и призван «прислуживать» ему. Он передает запросы со стороны клиента на сторону сервера, а также занимается транспортировкой данных с клиента на сервер и обратно.

Итак, давайте рассмотрим несколько особенностей работы программного кода в «1С:Предприятие 8», написанного под разными директивами.

Действие 1. Открытие пользователем формы с данными.

Рисунок 4

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

Действие 2. Получение из открытой Пользователем формы дополнительных данных из Базы данных.

Рисунок 6

Получение этих данных может быть описано под двумя директивами – «&НаСервере» и «&НаСервереБезКонтекста». Рассмотрим оба случая.

Явление 1. Директива «&НаСервере»

Рисунок 7
При вызове процедуры или функции под директивой «&НаСервере» из формы со стороны клиента происходит «упаковка» всего контекста формы и отправка его на сторону сервера.

После выполнения метода на сервере, весь этот «пакет» транспортируется обратно. Таким образом, форма со всеми элементами и данными дважды проходит через самое узкое место системы.

Явление 2. Директива «&НаСервереБезКонтекста»

Рисунок 8
При вызове процедуры или функции под директивой «&НаСервереБезКонтекста» из формы со стороны клиента происходит передача на сторону сервера только тех данных, которые были указаны в качестве параметров. Обратно же передаётся только необходимая информация в уже подготовленном виде.

Таким образом, серверный вызов не несёт лишней нагрузки, и для передачи данных между клиентом и сервером потребуется меньше ресурсов.

Из примеров видно, что далеко не всегда оправдано указание директивы компиляции «&НаСервере» с точки зрения использования контекста (данных) формы на сервере.

Если возможно решить возникшую задачу путём отправки на сервер только определённого набора данных, то надо эту возможность использовать и описывать метод под директивой «&НаСервереБезКонтекста». Это позволит уменьшить нагрузку на серверный вызов, а также не занимать сервер обработкой и хранением ненужной в текущий момент информации.

Кстати, именно поэтому до версии платформы 8.3.7.1759 на сложных формах для управления видимостью элементов рекомендовалось использовать панели со страницами, а не свойство «Видимость». Только начиная с этого релиза отработка изменения видимости элементов стала выполняться на стороне клиента.

До этого момента при каждом изменении свойства «Видимость» происходил серверный вызов, как при использовании директивы «&НаСервере».

Но использование директивы «&НаСервереБезКонтекста» не является панацеей. Помимо нагрузки на серверный вызов, всегда необходимо задумываться ещё над одним параметром.

Действие 3. Обработка данных табличной части формы с получением дополнительной информации из Базы данных.

Рисунок 9

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

Мы уже знаем – лучше использовать директиву «&НаСервереБезКонтекста».

Рисунок 10

Рисунок 11
При таком построении программного кода происходит множественное обращение со стороны клиента на сервер – по количеству элементов цикла, запущенного на стороне клиента.

Явление 2. Предварительная обработка табличной части на стороне клиента с целью подготовки требуемых к обработке на сервере данных и «упаковки» их в набор параметров. Затем передача этого набора на сервер для получения дополнительной информации из базы данных.

Используем всё ту же директиву «&НаСервереБезКонтекста».

Рисунок 12
В данном случае количество серверных вызовов сведено к минимуму за счёт предварительной подготовки параметров.

Большое количество текущих серверных вызовов может свидетельствовать о неоптимальном программном коде.

Избегайте создания серверных вызовов внутри цикла. Подготовьте набор параметров и единожды выполните его передачу для обработки на сервер. Если предполагается сложная обработка большого количества данных формы – передайте её полностью на сервер (при помощи директивы «&НаСервере») и выполните все действия на стороне сервера.

Если цель серверного вызова, созданного внутри цикла – получить какую-либо информацию из базы данных, то данная операция включает в себя запрос в цикле. А это очень негативно влияет на производительность всей системы в целом.

С директивой «&НаСервереБезКонтекста» вроде бы разобрались. Она нужна для того, чтобы уменьшить объем информации, передаваемой в рамках одного серверного вызова. Дополнительно разобрались с количеством текущих серверных вызовов – необходимо стремиться к их минимизации.

Давайте теперь попробуем разобраться, для чего нужна директива «&НаКлиентеНаСервереБезКонтекста».

Действие 4. Выполнение обработки данных.

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

Рисунок 13

Та-дам!

Рисунок 14

Для копирования у нас есть ксерокс. Но куда его поставить? На сторону клиента или сервера? Под какой директивой его разместить?

Как было озвучено ранее – любая процедура и функция поддерживает обработку информации, переданной в неё в качестве параметров.

Давайте для начала попробуем разместить копировальный аппарат на стороне клиента. Для этого описываем процедуру или функцию «Ксерокс» под директивой «&НаКлиенте». Тогда процесс клиентской части в любой момент сможет без проблем обратиться к ней и все действия будут выполнены в соответствии с программным кодом.

Но что произойдёт, если потребность в копировании возникнет на стороне сервера? Например, для подготовки данных, передаваемых на сторону клиента, потребуется сделать копию? Напомню – процесс серверной части не имеет возможности самостоятельно инициировать клиентские вызовы.

Рисунок 15

Получается, что использовать директиву «&НаКлиенте» неправильно, а директиву «&НаСервере», как мы изучили ранее – нежелательно. Давайте посмотрим поведение системы при использовании директивы «&НаСервереБезКонтекста».

Рисунок 16

Вроде бы результат достигнут – и с сервера, и с клиента доступно копирование. Но для того, чтобы получить копию данных, используемых на клиенте, приходится делать серверный вызов. А это опять ведет к лишней нагрузке на соединение и временным затратам.

Избавиться от излишней передачи на сервер при сохранении возможности копирования на клиенте и на сервере можно при помощи директивы «&НаКлиентеНаСервереБезКонтекста».

Рисунок 17

Не углубляясь в детали, отметим, что метод, описанный под данной директивой управления, создаётся в двух копиях – и на стороне клиента, и на стороне сервера. Это позволяет выполнить необходимые действия там, где появилась потребность в них (клиент/сервер), без лишних серверных вызовов.

Конечно, вместо того чтобы выделять повторяющийся программный код, описывать его в отдельном методе под директивой «&НаКлиентеНаСервереБезКонтекста», можно поступить по-другому. Просто взять и написать один и тот же участок кода и в клиентской, и в серверной процедуре.

С точки зрения выполнения программы результат будет одинаков. Но объяснение «почему так не надо делать» – это уже совершенно другая тема…

Вместо заключения

В данной статье мы на наглядных примерах рассмотрели влияние различных директив компиляции на такое явление системы «1С:Предприятие 8», как серверный вызов. Как видно, основная причина для выбора правильной директивы – производительность транспортировки данных между клиентской и серверной частью.

Придерживайтесь при разработке следующих правил:

  • По возможности не передавайте контекст формы на сторону сервера
  • Минимизируйте количество текущих серверных вызовов
  • Длительные и ресурсоёмкие задачи запускайте на выполнение на стороне сервера (при возможности – в фоновом режиме).

Учитывайте потребность в доступности тех или иных видов данных, обоснованность передачи управления и не стесняйтесь при необходимости дробить процедуры и функции. И будет Вашему серверному вызову всегда легко, а Вы от пользователей Вашей программы получите «молчаливую благодарность»!

Так ли это важно думать об оптимизации? Тут имеет смысл вспомнить одну историю.

Программист Иван при доработке 1С на своём предприятии сделал ошибку в выборе директивы компиляции. Из-за неё длительность одного из серверных вызовов была больше возможной на полсекунды.

Пользователей, применяющих этот функционал, – 25 человек, и каждый из них за рабочий день в среднем совершает 110 таких операций. Всего впустую за рабочий месяц потрачено 28875 секунд (21 рабочий день * 25 человек * 110 операций * 0,5 секунды) = 8,02 часов.

Иван, каково тебе осознавать, что за месяц ты задолжал своему предприятию целый рабочий день?

Об авторе

Автор статьи – Павел Ванин

г. Владимир

E-mail: pahich@mail.ru

PDF-версия статьи для участников группы ВКонтакте

Мы ведем группу ВКонтакте – http://vk.com/kursypo1c.

Если Вы еще не вступили в нее – сделайте это сейчас, и в блоке ниже (на этой странице) появятся ссылки на скачивание материалов.


Статья в PDF-форматеСтатья в PDF-формате
Вы можете скачать эту статью в формате PDF по следующей ссылке: Ссылка доступна для зарегистрированных пользователей)

Если Вы уже участник группы – нужно просто повторно авторизоваться в ВКонтакте, чтобы скрипт Вас узнал. В случае проблем решение стандартное: очистить кэш браузера или подписаться через другой браузер.

114 комментариев к “[ Наглядно о непонятном ] – Как работает серверный вызов в 1С

  1. forcef117 сказал:

    Имеет ли смысл указывать директиву “&НаСервереБезКонтекста” для метода, вызываемого из метода с директивой “&НаСервере” с т.з. повышения производительности?

    • Павел Ванин сказал:

      Нет. В данном случае контекст формы уже передан на сервер и никакой оптимизации не будет.

      Директиву “&НаСервереБезКонтекста” с целью оптимизации необходимо использовать для вызова из клиентских процедур и функций.

  2. Наталья Яковлева сказал:

    Спасибо, Мастер!
    Теперь понятны директивы, которыми пользовалась интуитивно. И на вопросы о которых во время прохождения тестов никак не могла ответить.
    Еще бы подобную статью по событиям управляемых форм. Просто нужна теория как фундамент для разработки удобных отчетов и обработок для заказчика.
    Спасибо!

    • Кузьмин Сергей сказал:

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

  3. alex56 сказал:

    Спасибо за статью. Наконец-то за один раз всё понял и запомнил. Коммиксы супер!

  4. Антон сказал:

    Знал все, но сомневался в последней директиве, которую кстати никогда не использовал. Оказывается, это там самая, которая могла сохранить кучу времени и читаемость кода)))

  5. Денис сказал:

    Павел, гениальная статья! Все очень понятно и запоминается моментально. Позвольте выразить Вам мое почтение! Спасибо Вам огромное!!!

  6. bmp12345 сказал:

    Даже удивительно! Как всё просто и понятно после такого изложения материала. Хочется поделиться со всеми, кто пока об этом не знает.
    Спасибо, МАСТЕР!

  7. Алексей сказал:

    Одно из самых доступнейших изложений материала. Подача материала в виде комикса – хороший ход. Нигде такого не встречал, применительно к 1С. Для себя повторил материал, изученный по базовому курсу.
    Спасибо :-)

  8. seniorsolder сказал:

    Иван, который задолжал за месяц всего один день работы из-за неоптимального кода – это так себе Иван. Он, видимо, не познал всей сути 1С:Дзен. Есть Иваны, которые своим кодом за один день тормозят работу на месяц.

    • Pahich сказал:

      :) Согласен!

      Эта статья и другие материалы данного ресурса нацелены как раз на то, чтобы увеличить «1С-Грамотность» всех участников «1С:Дзена» :)

  9. Александр сказал:

    Интересное изложение, однозначно +++, но конечно для себя конечно ничего нового не нашел.
    Считаю что 1С сама виновата в том что сделал такой подход, что 95% пользуется директивой НаСервере. Им как минимум надо было бы поменять значений директив, т.е. НаСервере – чтоб выполнялось без контекста (и создавалось по умолчанию, а директива НаСеререСКонтекстом – уже с контекстом, тогда вольно/невольно но большинство разработчиков бы стало более правильно использовать их.

    • seniorsolder сказал:

      Все эти контексты – это изобретение 1С, как обычно. Нормальные среды разработки сами определяют, где выполняться коду. Клиент-сервер – это низкий уровень, зачем туда 1С из надстройки над языком верхнего уровня полезла – непонятно.

  10. Николай Зайков сказал:

    Спасибо автору, наконец-то разобрался с директивой &НаКлиентеНаСервереБезКонтекста.

  11. sun-alena@yandex.ru сказал:

    Одна из самых понятных и доступных статей!!! Могу ли я почитать другие статьи Павла Ванина? очень подача материала понравилась!

    • Татьяна Гужавина сказал:

      В ближайшее время планируются новые статьи от Павла. Следите за новостями на нашем сайте.

  12. Ирина сказал:

    Согласна со всеми авторами: Превосходное наглядное, детальное описание темы! Запомнилось “на раз!”. Благодарю !!!

  13. Антон Штырляев сказал:

    Спасибо за статью, очень наглядное и лаконичное объяснение, пока лучшее, что я видел по этой теме.

  14. Александр сказал:

    Отличная статья, т.к. тему знаю было особенно увлекательно. Ассоциация с библиотекой просто супер.

  15. Saint сказал:

    Прочел. Ничего нового для себя не нашел. НО….
    Автор просто умничка. За такой подход к изложению темы, плюс!
    Спасибо за труды!!! И как сказал Сигизмунд: буду теперь эту статью кидать, чем объяснять.

  16. Андрей Мастер сказал:

    Со своей стороны хочу поблагодарить творчески подошедшего к этой не простой теме автора !

    Ждем продолжения !

  17. Сигизмунд сказал:

    Статья просто супер. Вместо того, что бы каждый раз “молодым” объяснять – буду теперь эту статью кидать))

  18. Feerija сказал:

    Долго искала кнопку Like, не нашла, поэтому пишу комментарий! После такой статьи точно не забудешь про директиву компиляции. Спасибо!!!

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Мы используем файлы cookies, чтобы сделать сайт удобнее.
Продолжая просмотр сайта, Вы соглашаетесь с их использованием.
Подробнее