Введение
Некоторое время назад 1С выпустила тестовые релизы новой версии платформы 8.3.26. Среди прочего, в ней был реализован новый механизм "Уведомления клиента".
Теория
В глобальном контексте появилось новое свойство УведомленияКлиента, содержащее три метода:
- ПодключитьОбработчик - назначает обработчик для входящего уведомления в клиентском коде;
- ОтключитьОбработчик - отключает ранее подключенный обработчик;
- ОтправитьУведомление - отправляет уведомление клиентским сеансам с сервера.
Уведомление может быть отправлено всем активным сеансам, либо определенному множеству сеансов. Для этого в ОтправитьУведомление можно передать массив номеров сеанса.
Также, в типе ФоновоеЗадание появилось новое свойство НомерРодительскогоСеанса. Его можно использовать, например, для отправки уведомлений о прогрессе выполнения длительной фоновой операции.
Разработчики заявляют, что механизм уведомлений клиента гарантирует доставку уведомления - уведомление не будет утеряно из-за временного обрыва соединения со стороны клиентского приложения или при падении рабочего процесса сервера 1С.
Пример использования
В качестве примера реализуем простейший мессенджер:
Подготовка клиентского кода
Пропишем подключение и отключение обработчика:
&НаКлиенте
Процедура ПриОткрытии(Отказ)
Обработчик = Новый ОписаниеОповещения("ПриПриемеСообщения", ЭтотОбъект);
УведомленияКлиента.ПодключитьОбработчик("СообщениеПереписки", Обработчик);
КонецПроцедуры
&НаКлиенте
Процедура ПриЗакрытии(ЗавершениеРаботы)
УведомленияКлиента.ОтключитьОбработчик("СообщениеПереписки");
КонецПроцедуры
Реализуем сам обработчик:
&НаКлиенте
Процедура ПриПриемеСообщения(ДанныеСообщения, ДополнительныеПараметры = Неопределено) Экспорт
СтрСообщения = Сообщения.Вставить(0);
СтрСообщения.Отправитель = ДанныеСообщения.Отправитель;
СтрСообщения.Текст = ДанныеСообщения.Текст;
СтрСообщения.Дата = МестноеВремя(ДанныеСообщения.Дата);
Состояние(ДанныеСообщения.Отправитель + " пишет!",, ДанныеСообщения.Текст);
КонецПроцедуры
Реализация отправки и доставки сообщений
В обработчике кнопки "Отправить сообщение" ничего необычного - спрашиваем текст и вызываем некоторую серверную процедуру:
&НаКлиенте
Асинх Процедура НаписатьСообщение(Команда)
Если Не ЗначениеЗаполнено(МоеИмя) Тогда
ПоказатьПредупреждение(, "Чтобы написать сообщение, укажите свое имя");
Возврат;
КонецЕсли;
Текст = Ждать ВвестиСтрокуАсинх("", "Наберите сообщение");
Если Текст = Неопределено Тогда
Возврат;
КонецЕсли;
НаписатьСообщениеНаСервере(МоеИмя, Текст);
КонецПроцедуры
А как отправить сообщение уже с сервера другим сеансам, в которых открыта эта же обработка? Записывать данные в какой-то регистр и стучаться в него раз в несколько секунд? Писать тонну кода для отправки и приема из системы взаимодействия? Нет, все гораздо проще:
&НаСервереБезКонтекста
Процедура НаписатьСообщениеНаСервере(Знач МоеИмя, Знач Текст)
ДанныеСообщения = Новый Структура("Дата, Отправитель, Текст");
ДанныеСообщения.Дата = ТекущаяУниверсальнаяДата();
ДанныеСообщения.Отправитель = МоеИмя;
ДанныеСообщения.Текст = Текст;
УведомленияКлиента.ОтправитьУведомление("СообщениеПереписки", ДанныеСообщения);
КонецПроцедуры
В процедуре я подготовил произвольную структуру данных сообщения (в отличие от системы взаимодействия, я могу передавать не только строку) и вызвал УведомленияКлиента.ОтправитьУведомление. Т.к. я не передавал массив с номерами сеансов, уведомление отправится всем активным сеансам ИБ (включая текущий).
Демонстрация

Проверено на следующих конфигурациях и релизах:
- Управление торговлей, редакция 11, релизы 11.5.18.46
Вступайте в нашу телеграмм-группу Инфостарт