1С передать сообщение с сервера на клиент

1С передать сообщение с сервера на клиент

В 1С предполагается, что СообщениеПользователю выводятся для того, чтобы сообщить пользователю об ошибках.

А для информирования о выполняемом действии рекомендуется использовать метод встроенного языка ПоказатьОповещениеПользователя().

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

Пример вывода сообщения на клиенте:

При обработке на сервере:

Необходимо зарегистрировать в системе соответствие объекта и имени реквизита формы. Для этого в глобальном контексте реализована функция УстановитьСоответствиеОбъектаИРеквизитаФормы(). Сделать это можно следующим образом:

В данном фрагменте выполняется преобразование объекта из данных формы в реальный объект и устанавливается его соответствие с реквизитом формы по имени "Объект".

Если в дальнейшем требуется создать сообщение, можно сделать это следующим образом:

В этом фрагменте создается новый объект СообщениеПользователю, в котором запоминается Текст сообщения и указывается Поле объекта, ошибка в данных которого вызвала необходимость вывода сообщения. Информация о том, как объект расположен в форме берется из предварительно запомненной пары "Объект/ИмяРеквизитаФормы". В дальнейшем сообщение будет выведено в окно сообщений формы и привязано к соответствующему элементу управления.

Примеры заполнения свойства Поле объекта СообщениеПользователю

ТипШаблонПример
Реквизит ИмяРеквизита Контрагент
Табличная часть ИмяТабличнойЧасти Скидки
Реквизит табличной части ИмяТабличнойЧасти[ИндексСтроки].ИмяРеквизита Номенклатура[10].Количество
Реквизит набора записей [ИндексСтроки].ИмяРеквизита [10].Курс

ПоказатьОповещениеПользователя — оповещение возникает в правом нижнем углу приложения и сообщает о совершенном действии. В течение нескольких секунд оно постепенно гаснет и пропадает. При этом, если навести на оповещение курсор мышки, оно не гаснет, и есть возможность внимательно его прочитать:

Данная статья является анонсом новой функциональности.
Не рекомендуется использовать содержание данной статьи для освоения новой функциональности.
Полное описание новой функциональности будет приведено в документации к соответствующей версии.
Полный список изменений в новой версии приводится в файле v8Update.htm.

Реализовано в версии 8.3.11.2867.

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

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

Основные возможности и сценарии

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

В клиентское приложение вы можете передавать данные, имеющие XDTO-сериализацию. Естественно типы передаваемых данных должны быть доступны на клиенте. Вы можете использовать передачу информации с сервера в клиентское приложение в самых разных сценариях. Например:

  • Для отображения прогресса длительной серверной операции;
  • Для уведомления пользователей о перезагрузке сервера и принудительного завершения клиентских приложений;
  • Для уведомления пользователя о входящем SIP-звонке;
  • Для поддержки прохождения бизнес-процессов;
  • Для реализации «напоминалок», уведомлений и пр.
Читайте также:  Asus zenfone max pro m1 asus shop

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

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

Общая схема очень простая. Вы создаёте отдельное обсуждение, в котором передаёте сообщения клиенту. Назовём такое обсуждение служебным. Клиентское приложение автоматически обрабатывает новые сообщения в этом обсуждении и выполняет нужные действия.

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

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

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

Если же в обсуждении участвует один пользователь, то будет задействовано одно соединение с его клиентским приложением.

Правды ради нужно сказать, что от имени одного пользователя может быть запущено несколько приложений. Но сути дела это не меняет. Если информацию с сервера нужно передать в то приложение, которое инициировало серверную операцию, эффективнее использовать отдельные служебные обсуждения для каждого пользователя, чем «пулять» по всем клиентам в одном общем служебном обсуждении. В этом случае ресурсы сервера взаимодействия будут использоваться бережнее, а нагрузка на него будет меньше.

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

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

Процедура СоздатьСлужебноеОбсуждение(КлючСлужебногоОбсуждения) Экспорт Если СистемаВзаимодействия.ПолучитьОбсуждение(КлючСлужебногоОбсуждения) = Неопределено Тогда Обсуждение = СистемаВзаимодействия.СоздатьОбсуждение(); Обсуждение.Отображаемое = Ложь; Обсуждение.Ключ = КлючСлужебногоОбсуждения; Обсуждение.Участники.Добавить(СистемаВзаимодействия.ИдентификаторТекущегоПользователя()); Обсуждение.Записать(); КонецЕсли; КонецПроцедуры Функция КлючСлужебногоОбсуждения() Экспорт Возврат "Сообщения сервера " + СистемаВзаимодействия.ИдентификаторТекущегоПользователя(); КонецФункции

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

Ещё одно новое свойство обсуждения будет вам полезно – Отображаемое. Для служебных обсуждений его лучше устанавливать в Ложь, тогда они не будут показаны в пользовательском интерфейсе.

Читайте также:  Amd radeon r5 310

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

&НаКлиенте Процедура ПодписатьсяНаСлужебноеОбсуждение(КлючСлужебногоОбсуждения) Экспорт ОшибкаПодключения = Новый ОписаниеОповещения( , , , "ОшибкаПодключения", СообщенияКлиент); ОбработкаСообщенийСервера = Новый ОписаниеОповещения("ОбработкаСообщенийСервера", СообщенияКлиент); СистемаВзаимодействия.НачатьПодключениеОбработчикаНовыхСообщений(ОшибкаПодключения, КлючСлужебногоОбсуждения, ОбработкаСообщенийСервера); КонецПроцедуры &НаКлиенте Процедура ОбработкаСообщенийСервера(Сообщение, ДополнительныеПараметры) Экспорт . &НаКлиенте Процедура ОшибкаПодключения(ДополнительныеПараметры) Экспорт .

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

Теперь вы можете на сервере отправить сообщение в служебное обсуждение, и приложение, подписанное на это обсуждение, автоматически его обработает.

В настоящее время в Библиотеке стандартных подсистем (БСП) реализован механизм выполнения длительных операций на сервере, который использует фоновые задания. Это позволяет распараллелить исполнение прикладного кода на сервере и освободить пользовательский сеанс.

В этом примере необходимо использовать ту же самую механику.

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

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

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

Запуск фонового задания может выглядеть таким образом:

&НаКлиенте Процедура ОбработатьДанные(Команда) // Запустить фоновое задание. ИдентификаторЗадания = ОбработатьФоновымЗаданием(КлючСлужебногоОбсуждения); // Запомнить идентификатор запущенного задания в глобальной клиентской переменной. ИдентификаторыЗаданий.Добавить(ИдентификаторЗадания); КонецПроцедуры &НаСервереБезКонтекста Функция ОбработатьФоновымЗаданием(КлючСлужебногоОбсуждения) // Создать идентификатор фонового задания, чтобы: // — передать его в само задание, // — вернуть его на клиента. ИдентификаторЗадания = Строка(Новый УникальныйИдентификатор); Параметры = Новый Массив; Параметры.Добавить(КлючСлужебногоОбсуждения); Параметры.Добавить(ИдентификаторЗадания); ФоновыеЗадания.Выполнить("СообщенияСервер.ОбработатьДанныеНаСервере", Параметры); Возврат ИдентификаторЗадания; КонецФункции

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

А длительная операция, выполняемая на сервере, может выглядеть так:

Процедура ОбработатьДанныеНаСервере(КлючСлужебногоОбсуждения, ИдентификаторЗадания) Экспорт // Получить обсуждение, т.к. его идентификатор понадобится для создания сообщений. СлужебноеОбсуждение = СистемаВзаимодействия.ПолучитьОбсуждение(КлючСлужебногоОбсуждения()); // Создать структуру данных для передачи её в сообщении: // — ИдентификаторЗадания — чтобы клиент мог определить, его ли это фоновое задание // — Значение — значение, которое надо обработать на клиенте // — СпособОбработки — способ, которым надо обработать значение // (отобразить в индикаторе, показать как текст и т.д.) СтруктураДанных = Новый Структура; СтруктураДанных.Вставить("ИдентификаторЗадания", ИдентификаторЗадания); СтруктураДанных.Вставить("Значение", 0); СтруктураДанных.Вставить("СпособОбработки", "Индикатор"); // Длительный алгоритм, состоящий из 100 этапов. Для Счетчик = 1 По 100 Цикл // Сообщение клиенту. СтруктураДанных.Значение = Счетчик; Сообщение = СистемаВзаимодействия.СоздатьСообщение(СлужебноеОбсуждение.Идентификатор); Сообщение.Данные = СтруктураДанных; Сообщение.Записать(); КонецЦикла; // Сообщение о завершении фонового задания. СтруктураДанных.СпособОбработки = "НеОтслеживать"; Сообщение = СистемаВзаимодействия.СоздатьСообщение(СлужебноеОбсуждение.Идентификатор); Сообщение.Данные = СтруктураДанных; Сообщение.Записать(); КонецПроцедуры
Читайте также:  310 Код какой страны

Здесь на каждом этапе длительного алгоритма посылается сообщение в служебное обсуждение, а в конце посылается сообщение, сигнализирующее о завершении задания. В данных сообщения передаётся идентификатор этого задания, какое-либо значение, которое нужно обработать на клиенте, и способ его обработки. Способ обработки может понадобиться потому, что этот механизм вы можете использовать в разных алгоритмах своего прикладного решения. В одном алгоритме, например, нужно передвинуть полосу индикатора, а в другом – вывести надпись в форму.

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

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

Сначала вы определяете, «ваше» ли это фоновое задание (его идентификатор сохранён в глобальном массиве), затем смотрите, как нужно обработать переданное значение. В одном случае, для примера, вы передвигаете индикатор, а в другом удаляете идентификатор из массива отслеживаемых заданий, потому что задание завершилось.

Заключение

Как вы видите механизм довольно гибкий. И это позволяет использовать его для самых разных задач. Приведённый пример это лишь один из сценариев, как говорится, «в лоб».

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

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

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

Если ли какие-нибудь токовые компоненты, чтобы реализовать подобную схему Т.е. в чем суть:

Клиенты подключаются к 1С через серверное соединение или через WEB сервер

  • Сервер знает, что клиент подключен и держит какой-нибудь канал с каждым клиентом
  • При необходимости сервер посылает пакет клиенту, клиент получает и обрабатывает (только в том случаи если сервер посылает пакеты данных)
  • Пакет данных содержит только строковое значение (т.е. тип значения строка)

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

но 1С так и не выпускает данный механизм, когда выпустят тоже не известно.

Реализация на регистрах сведений или через фоновое задание или методом ПодключитьОбработчикОжидания – не пойдёт

Буду очень признателен за направления или подсказки

Ссылка на основную публикацию
Adblock detector