При переходе с файловых информационных баз на клиент-серверный вариант работы разработчики часто сталкиваются с иллюзией того, что серверный код не вызывается. Типичный сценарий: на управляемой форме расположено поле ввода со ссылочным типом данных и кнопка. При нажатии на кнопку в режиме пошаговой отладки по клавише F11 курсор останавливается на строке клиентской процедуры, а при следующей итерации шаг просто перескакивает вызов серверной процедуры, не заходя внутрь. Разберем по шагам, почему это происходит, как настроить серверную отладку и как правильно работать со ссылками и объектами при вызове сервера.
Проанализируем механику работы клиент-серверной архитектуры платформы «1С:Предприятие 8.3». По умолчанию служба кластера серверов 1С функционирует в рабочем (продуктивном) режиме, при котором протоколы отладки выключены для экономии системных ресурсов. В файловой базе все вызовы выполняются в рамках одного локального процесса, поэтому отладчик без дополнительных настроек заходит в процедуры с директивами &НаКлиенте, &НаСервере и &НаСервереБезКонтекста.
В клиент-серверной базе клиентское приложение и серверный кластер представляют собой разные процессы, часто работающие на физически разделенных машинах. Если на сервере не активирован отладочный режим, серверная процедура фактически выполняется, однако Конфигуратор не может перехватить поток исполнения. В результате создается ложное впечатление, что вызов игнорируется платформой.
Рассмотрим, как запустить службу кластера серверов с параметром отладки. Выполним следующие действия в зависимости от используемой операционной системы:
Откроем редактор реестра regedit от имени администратора. Перейдем к ветке системных служб: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ и найдем службу агента сервера 1С (например, 1C:Enterprise 8.3 Server Agent...). В строковом параметре ImagePath найдем исполняемую команду и допишем в самый конец строки через пробел ключ -debug. Если используется отладка по протоколу HTTP (актуально для платформ начиная с 8.3.7), укажем параметры -http -debug. После редактирования реестра перезапустим службу 1С через консоль управления службами.
В Linux конфигурация службы агента кластера ragent обычно располагается в файле инициализации (например, /etc/init.d/srv1cv83 или в параметрах сервиса systemd). Добавим параметр -debug в строку запуска сервера и выполним перезапуск соответствующего сервиса командой systemctl restart srv1cv83.
Откроем Конфигуратор, перейдем в главное меню: «Сервис» — «Параметры» — вкладка «Отладка». Убедимся, что установлены флажки автоматического подключения для пунктов «Сессии на сервере» и «Фоновые задания». Затем откроем меню «Отладка» — «Подключение...» и проверим, присоединен ли текущий сеанс к серверным предметам отладки.
Убедимся, что локальный брандмауэр на стороне сервера не блокирует входящий трафик отладчика. Для классического протокола отладки TCP кластер использует диапазон портов 1560–1591.
Если прямо сейчас у нас нет прав администратора для перезапуска службы агента сервера, проверим фактическое исполнение кода альтернативными способами. Рассмотрим три практических метода диагностики:
&НаСервере
Процедура ВыполнитьДействиеНаСервере()
ВызватьИсключение "Серверная процедура успешно вызвана!";
КонецПроцедуры
&НаСервере
Процедура ВыполнитьДействиеНаСервере()
ЗаписьЖурналаРегистрации("ТестВызова", УровеньЖурналаРегистрации.Информация, , , "Код на сервере отработал.");
КонецПроцедуры
&НаСервере
Функция ВыполнитьДействиеНаСервере()
// Выполнение алгоритма
Возврат Истина;
КонецФункции
&НаКлиенте
Процедура НажатиеКнопки(Команда)
Если ВыполнитьДействиеНаСервере() Тогда
ПоказатьОповещениеПользователю("Сервер отработал штатно");
КонецЕсли;
КонецПроцедуры
Проанализируем вторую часть вопроса: особенности работы с типами СправочникСсылка и СправочникОбъект.
Ссылочные типы (например, СправочникСсылка.Номенклатура или ДокументСсылка.ПриходнаяНакладная) являются неизменяемыми (немутабельными) и сериализуемыми. Их можно передавать в качестве параметров между контекстами клиента и сервера без каких-либо ограничений. Объектные типы (СправочникОбъект) являются мутабельными: они не могут существовать на клиенте и не передаются через границу клиент-сервер.
Рассмотрим два правильных варианта реализации алгоритма.
Вариант 1. Использование контекстной серверной процедуры (&НаСервере)
Если поле ввода на форме связано с реквизитом обработки (путь к данным Объект.ВыбДок), то данное значение уже присутствует в контексте формы. Передавать его отдельным параметром в процедуру с директивой &НаСервере не требуется — обратимся к нему напрямую:
&НаКлиенте
Процедура КомандаОбработать(Команда)
// Дополнительные параметры не нужны, форма отправляет контекст на сервер
ОбработатьДанныеНаСервере();
КонецПроцедуры
&НаСервере
Процедура ОбработатьДанныеНаСервере()
СсылкаНаОбъект = Объект.ВыбДок;
Если ЗначениеЗаполнено(СсылкаНаОбъект) Тогда
// Получаем объект из ссылки для модификации реквизитов
РедактируемыйОбъект = СсылкаНаОбъект.ПолучитьОбъект();
РедактируемыйОбъект.Наименование = "Новое наименование";
РедактируемыйОбъект.Записать();
КонецЕсли;
КонецПроцедуры
Вариант 2. Оптимизированный вызов без контекста (&НаСервереБезКонтекста)
Для ускорения работы интерфейса рекомендуется минимизировать объем передаваемых данных формы и использовать вызовы без контекста. В этом случае мы передаем ссылку явным параметром:
&НаКлиенте
Процедура КомандаОбработать(Команда)
// Передаем ссылку параметром, не гоняя весь контекст формы
ОбработатьДанныеБезКонтекста(Объект.ВыбДок);
КонецПроцедуры
&НаСервереБезКонтекста
Процедура ОбработатьДанныеБезКонтекста(ВыбраннаяСсылка)
Если ЗначениеЗаполнено(ВыбраннаяСсылка) Тогда
ОбъектБД = ВыбраннаяСсылка.ПолучитьОбъект();
ОбъектБД.Комментарий = "Изменено из внешней обработки";
ОбъектБД.Записать();
КонецЕсли;
КонецПроцедуры
Таким образом, ссылка на элемент базы данных всегда успешно передается между клиентом и сервером. Если отладчик пропускает серверную часть кода, достаточно настроить запуск службы кластера серверов 1С с флагом -debug и проверить параметры подключения в Конфигураторе.