Часто возникает необходимость оповестить клиента о какой нибудь информации (Например о новом сформированном документе) с сервера. На данный момент, в типовых методах 1С нет возможности оповестить клиента с сервера, в основном существующие методы оповещения построены на принципе периодического "опроса" клиента на сервер. Проще говоря "обработчики ожидания". Многие разработчики используют обработчики ожидания, либо разрабатывают\используют внешние компоненты для реализации подобной задачи. Типовые механизмы: напоминания, уведомления, задачи ... так же используют периодический зарос сервера на появление новых данных.
Далее будет показан пример, как отправить уведомление с сервера на клиент используя команду (командной строки Windows ) - MSG.
"Команда MSG существовала еще в Windows 2000/XP и предназначалась для обмена сообщениями между пользователями вошедшими в систему локально и пользователями терминальных сессий ( подключившихся к удаленному рабочему столу ) . В Windows Vista и более поздних операционных системах семейства Windows команда MSG стала основным стандартным средством обмена сообщениями, поскольку команда net send в данных ОС больше не поддерживается."
Для примера возьмем небольшой код использования данного механизма:
///Модуль Web-Сервиса Пример1
Процедура СоданияДокумента(Параметры)
Чтение = Новый ЧтениеXML;
Чтение.УстановитьСтроку(Текст);
//прочитаем начало xml файла
Чтение.ПерейтиКСодержимому();
//прочитаем начало корневого элемента
Чтение.Прочитать();
//читаем содержимое пока текущим не станет конец корневого элемента, т.к. мы писали туда только целые элементы справочника,
//а сериализатор читает каждый из их полностью, то мы упремся именно в конец корневого
Пока Чтение.ТипУзла<>ТипУзлаXML.КонецЭлемента Цикл
НовыйДокумент = Документы.АвансовыйОтчет.СоздатьДокумент();
//читаем очередной элемент справочника
Объект = СериализаторXDTO.ПрочитатьXML(Чтение);
ЗаполнитьЗначенияСвойств(НовыйДокумент,Объект );
Попытка
НовыйДокумент.Записать(РежимЗаписиДокумента.Проведение);
///Записываем документ и отправляем уведомление о новом документе
ОповеститьПользователяОНовомДокументе(НовыйДокумент.Ссылка)
Исключение
ТекстОшибки = ОписаниеОшибки();
КонецПопытки;
КонецЦикла;
Чтение.Закрыть();
КонецПроцедуры
Процедура ОповеститьПользователяОНовомДокументе(Ссылка)
///Пример отправки уведомления
///Получим список активных пользователей Информационной базы
///Делаем отбор по "Бухгалтеру" и отправляем
Попытка
массивСоединений = ПолучитьСоединенияИнформационнойБазы(); ///Получаем список активных пользователей
Для каждого масс из массивСоединений цикл
Если масс.ИмяПриложения = "1CV8C" тогда ///1С Предприятие
Если масс.ИмяПользователя = "Бухгалтер" Тогда ///Отправляем уведомление Бухгалтеру
ИмяКомпьютера = масс.ИмяКомпьютера;
СтрокаМСГ = "MSG /time:1000 /server:"+ СокрЛП(ИмяКомпьютера)+" * " + "Сформирован новый документ: " + строка(Ссылка);;
ЗапуститьПриложение(СтрокаМСГ);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Исключение
ТекстОшибки = ОписаниеОшибки();
КонецПопытки;
///Либо сразу пропишем ИмяКомпьютера "Бухгалтера"
///В случае если Бухгалтер не работает в программе 1С на данный момент.
//Попытка
// ИмяКомпьютера = "buhgalter-1";
// СтрокаМСГ = "MSG /time:1000 /server:"+ СокрЛП(ИмяКомпьютера)+" * " + "Сформирован новый документ: " + строка(Ссылка);;
// ЗапуститьПриложение(СтрокаМСГ);
//Исключение
// ТекстОшибки = ОписаниеОшибки();
//КонецПопытки;
КонецПроцедуры
В примере рассматривается отправка уведомления Бухгалтеру.
Данную команду так же можно использовать для отправки уведомления пользователям локальной сети, как выборочно так и всем сразу.
Пример реализации:
///Получаем имена компьютеров локальной сети
///Заносим имена в табличную часть "Компьютеры"
&НаСервере
Процедура ПолучитьВсеКомпьютерыЛокальнойСети()
Компьютеры.Очистить();
///Для получения Списка локальных и терминальных пользователей используем команду
/// cmd - "Net View"
///Команда net view выводит список доменов, компьютеров или общих ресурсов на данном компьютере.
///Вызванная без параметров, команда net view выводит список компьютеров в текущем домене.
objShell = Новый COMОбъект("WScript.Shell") ;
objScriptExec = objShell.Exec("Net View") ;
strPingResults = НРег(objScriptExec.StdOut.ReadAll());
Для Индекс = 1 По СтрЧислоСтрок(strPingResults) Цикл
ПолучитьКомп(СтрПолучитьСтроку(strPingResults, Индекс));
КонецЦикла;
КонецПроцедуры
Процедура ПолучитьКомп(ММ) ///Форматируем имя компьютера (Удаляем лишние символы)
///Имя компьютера в локальной сети будет иметь вид: "\\Admin"
НачСлова = СтрНайти(ММ,"\\");
Если НачСлова = 0 тогда
возврат;
КонецЕсли;
КонСлова = СтрНайти(ММ," ",,НачСлова);
Комп = СокрЛП(Сред(ММ,НачСлова+2,КонСлова - НачСлова));
Компьютеры.Добавить().ИмяКомпьютера = Комп;
КонецПроцедуры
///В итоге получаем Таблицу с именами компьютеров в локальной сети
///Далее, выбираем нужных пользователей и отправляем уведомление
&НаСервере
Процедура ОтправитьУведомленияНаСервере()
Для каждого стр из Компьютеры цикл ///Пометка - вторая колонка Табличной части, для ручного выбора пользователей
Если стр.Пометка тогда
СтрокаМСГ = "MSG /time:1000 /server:"+ СокрЛП(стр.ИмяКомпьютера)+" * " + Сообщение;
ЗапуститьПриложение(СтрокаМСГ);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
&НаКлиенте
Процедура ОтправитьУведомления(Команда)
Если ПустаяСтрока(Сообщение) тогда
ПоказатьОповещениеПользователя("Отсутсвует сообщение!");
возврат;
КонецЕсли;
ОтправитьУведомленияНаСервере();
КонецПроцедуры
Параметры MSG и Возможные ошибки:
Нынешняя реализация msg.exe прекрасно подходит для обмена сообщениями между сеансами локальных и терминальных пользователей в пределах одной системы, однако, в случаях обмена между разными компьютерами локальной сети, потребуется изменить некоторые настройки безопасности, принятые по умолчанию в операционных системах Windows Vista, 7 и более поздних.
При стандартных настройках, отправка сообщения пользователям удаленных компьютеров не выполняется и сопровождается сообщением:
Ошибка 1722 при получении имен сеанса
Это означает, что на компьютере, где должно приниматься посылаемое сообщение, невозможно получить информацию о вошедших в систему пользователях. Причиной может быть то, что брандмауэр блокирует входящие соединения, недостаточны права пользователя по отношению к удаленной системе, запрет удаленного вызова процедур в параметрах службы сервера терминалов. Как минимум, для обмена сообщениями с использованием команды msg между компьютерами, необходимо иметь учетную запись пользователя, действительную по отношению к удаленной системе и выполнить следующие настройки:
на каждом компьютере, которому будут отправляться сообщения, добавить в раздел реестра HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server параметр AllowRemoteRPC типа REG_DWORD и равный 1 Для изменения настроек можно использовать .reg-файл следующего содержания:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server]
"AllowRemoteRPC"=dword:00000001
В ОС Windows Vista, Windows 7, 8, 10 ключ реестра AllowRemoteRPC существует, но имеет значение равное 0 , что необходимо исправить. Для применения изменений требуется перезагрузка.
поскольку для обмена сообщениями утилита msg.exe использует протокол SMB (Server Message Block ), на каждом компьютере, которому будут отправляться сообщения, должен быть открыт TCP порт 445
Примеры использования MSG:
msg * /server:Server "Тестовое сообщение " - отправить тестовое сообщение всем пользователям компьютера Server
msg * /server:192.168.0.1 "Тестовое сообщение " - отправить тестовое сообщение всем пользователям компьютера с IP-адресом 192.168.0.1
msg RDP-Tcp#0 /server:TSServer "Тестовое сообщение" - отправить тестовое сообщение пользователю терминальной сессии с именем RDP-Tcp#0 на компьютере TSServer
msg console /server:Windows7 "Тестовое сообщение" - отправить тестовое сообщение текущему локальному пользователю компьютера Windows7
msg console "Тестовое сообщение" - отправка тестового сообщения от пользователя сеанса RDP локальному пользователю. Если эта команда выполняется не пользователем терминальной сессии, то сообщение будет отправлено локальным пользователем самому себе.
Для выполнения команды msg от имени другого пользователя можно воспользоваться утилитой PSExec из пакета PSTools или штатным средством runas.exe
psexec -u otheruser -p otherpass msg * /server:win10 TEST message
runas /user:otheruser "msg * /server:win10 Test message"
Сообщения, отправляемые командой msg локальному пользователю компьютера с операционной системой Windows XP, который отсутствует ( еще не вошел в Windows ) отображаются в окне с приглашением к регистрации в системе и могут быть доступны посторонним.
Источник MSG.
К данной статье прикреплена обработка для отправки уведомления. Обработка тестировалась на конфигурации ЗУП (3.1.9.108).
Универсальная, подходит конфигурациям на управляемых формах.