В процессе автоматизации интенсивного документооборота нередко возникает бизнес-задача организации непрерывного конвейера. Например, когда один оператор фиксирует первичные данные (квитанции, обращения), а второй менеджер должен мгновенно подхватывать их и продолжать заполнение связанного документа (заказа, заявки). Рассмотрим технические ограничения платформы 1С, выясним, почему нельзя просто «приказать» чужому сеансу отобразить окно, и разберем надежные архитектурные паттерны решения этой задачи.
Для понимания архитектуры клиент-серверного взаимодействия в 1С 8.3 проанализируем базовые правила работы сеансов:
ОткрытьФорму() или интерфейсным окнам.Оповестить() и ОповеститьОбИзменении() рассылают сообщения исключительно в пределах одного конкретного клиентского сеанса и не выходят за его рамки.Наиболее современным и рекомендуемым способом передачи событий между разными сеансами без создания лишней нагрузки на базу данных является использование механизма «Система взаимодействия». При этом платформа берет на себя доставку оповещения через веб-сокеты в режиме реального времени.
Разберем логику работы по шагам:
Посмотрим на пример отправки сообщения из серверного модуля после создания исходного документа:
// Серверная процедура отправки уведомления адресату
ПользовательПолучатель = ПользователиИнформационнойБазы.НайтиПоИмени("МенеджерЗаказов");
ИдентификаторПолучателя = СистемаВзаимодействия.ПолучитьИдентификатор(ПользовательПолучатель.УникальныйИдентификатор);
НовоеСообщение = СистемаВзаимодействия.СоздатьСообщение();
НовоеСообщение.Получатели.Добавить(ИдентификаторПолучателя);
НовоеСообщение.Текст = "Поступила новая квитанция к обработке!";
// Передаем ссылку на созданный документ в свойствах данных
ПараметрыДанных = Новый Структура;
ПараметрыДанных.Вставить("СсылкаНаОбъект", СсылкаНаНовыйДокумент);
НовоеСообщение.Данные = Новый ХранилищеЗначения(ПараметрыДанных);
НовоеСообщение.Записать();
На стороне клиента-получателя в модуле управляемого приложения подключается обработчик входящих сообщений. В зависимости от статуса оператора форма может открываться автоматически (если включен режим ожидания конвейера) либо отображаться через ПоказатьОповещениеПользователя() со ссылкой на навигацию.
Если Система взаимодействия в конфигурации не подключена, классическим решением выступает периодический опрос базы данных (Pull-модель) с использованием клиентского метода ПодключитьОбработчикОжидания(). Обратите внимание: регламентные задания здесь не требуются, так как опрос должен инициироваться именно клиентским сеансом оператора.
Рассмотрим структуру данного решения:
Посмотрим на пример запуска обработчика в форме рабочего места оператора:
&НаКлиенте
Процедура ПриОткрытии(Отказ)
// Подключаем проверку очереди каждые 3 секунды
ПодключитьОбработчикОжидания("ПроверитьОчередьДокументов", 3, Ложь);
КонецПроцедуры
&НаКлиенте
Процедура ПроверитьОчередьДокументов()
// Проверяем, свободен ли оператор в данный момент
Если Не ОператорГотовКНовойЗадаче() Тогда
Возврат;
КонецЕсли;
СсылкаНаДокумент = ПолучитьСледующийДокументИзОчередиНаСервере();
Если ЗначениеЗаполнено(СсылкаНаДокумент) Тогда
ПараметрыФормы = Новый Структура("Ключ", СсылкаНаДокумент);
ОткрытьФорму("Документ.ЗаказКлиента.ФормаОбъекта", ПараметрыФормы);
КонецЕсли;
КонецПроцедуры
Важное предостережение: Метод постоянного опроса через обработчик ожидания создает паразитную нагрузку на серверную базу данных и сеть, если интервал слишком мал, а пользователей много. Кроме того, при конкурентной работе нескольких принимающих операторов серверную выборку следующей записи необходимо защищать с помощью объекта БлокировкаДанных, чтобы исключить состояние гонки, когда один и тот же документ откроется одновременно у двоих сотрудников.
Проанализируем опыт проектирования высоконагруженных конвейеров. Прямое принудительное открытие формы у коллеги — не всегда удачное UX-решение. Скорость работы сотрудников различается: первый оператор может за минуту создать 5 квитанций, в то время как второй успеет заполнить только один сложный заказ. В результате у второго оператора на экране откроется множество вкладок, что вызовет зависание программы или потерю введенных строк.
Вместо жесткой синхронизации эффективнее использовать паттерн «Пул задач»:
Такой подход полностью устраняет конфликты фокуса ввода, защищает сеанс от перегрузки открытыми окнами и балансирует неравномерную нагрузку между операторами.