При интеграции 1С со сторонним программным обеспечением через COM-технологии разработчики часто сталкиваются с серьезным ограничением платформы: механизм обратных вызовов (событий) отлично работает на клиенте, но оказывается совершенно неработоспособным в серверном контексте или в фоновых заданиях. Рассмотрим подробнее, почему так происходит и какие существуют надежные способы обхода этого ограничения.
Для начала разберем техническую причину. Когда мы используем команду ДобавитьОбработчик для COM-объекта в тонком или толстом клиенте, 1С задействует механизмы Windows Message Loop (петля сообщений). COM-объект, генерируя событие, отправляет уведомление в поток приложения, который находится в состоянии ожидания. Процесс rphost (рабочий процесс сервера 1С), в отличие от клиентского приложения, работает в неинтерактивном режиме как сервис. У него нет «окна» и классической петли сообщений, которая необходима для интерфейсов типа IConnectionPoint.
Кроме того, серверные потоки в 1С являются частью пула потоков. Они могут динамически создаваться и уничтожаться. Если вы создадите COM-объект в фоновом задании и подпишетесь на события, поток может завершить свою работу сразу после выполнения кода, не дождавшись самого события. Даже если организовать бесконечный цикл ожидания, серверный контекст просто «не услышит» входящий RPC-вызов от COM-сервера.
Проанализируем ситуацию: автору задачи требуется реакция в реальном времени даже при отсутствии активных пользователей. Это означает, что нам нужно решение, работающее 24/7. Рассмотрим основные стратегии реализации такой задачи.
Это самый простой в реализации метод, который не требует написания кода на сторонних языках программирования. Разберем его по шагам:
Robot_COM_Listener).Пример кода для клиентского приложения:
// В модуле управляемого приложения или обработки
Перем МойCOMОбъект;
Процедура ПриНачалеРаботыСистемы()
#Если ТонкийКлиент Или ТолстыйКлиентОбычноеПриложение Тогда
МойCOMОбъект = Новый COMОбъект("ExternalSoftware.Application");
ДобавитьОбработчик МойCOMОбъект.OnNewData, ОбработкаСобытияНовыхДанных;
#КонецЕсли
КонецПроцедуры
Процедура ОбработкаСобытияНовыхДанных(Данные)
// Здесь мы можем вызвать серверный метод для записи в регистр
ЗаписатьСобытиеНаСервере(Данные);
КонецПроцедуры
Важный момент: Для обеспечения отказоустойчивости рекомендуется использовать планировщик задач Windows, который будет проверять, запущен ли процесс 1cv8c.exe, и перезапускать его в случае падения. Это решение превращает клиентское приложение в своего рода «сервисный процесс».
Если мы хотим избежать запуска лишних клиентских сеансов 1С, нам потребуется создать внешнее приложение-посредник. Рассмотрим архитектуру этого решения: стороннее ПО генерирует событие -> «прокладка» ловит событие -> «прокладка» отправляет HTTP-запрос в 1С.
Выясним причину, почему это надежнее: внешний процесс (написанный на C#, Python или даже в виде скрипта PowerShell) имеет собственную петлю сообщений и может работать как полноценная служба Windows. Он не зависит от сеансов 1С и может буферизировать данные, если сервер 1С временно недоступен.
В самой 1С нам необходимо создать HTTP-сервис с методом POST. Разберем примерную структуру метода в 1С:
Функция ОбработатьСобытие(Запрос)
Тело = Запрос.ПолучитьТелоКакСтроку();
// Логика парсинга данных (например, из JSON)
ДанныеJSON = ПрочитатьJSONДанные(Тело);
МенеджерЗаписи = РегистрыСведений.ИсторияСобытий.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Период = ТекущаяДата();
МенеджерЗаписи.Событие = ДанныеJSON.EventName;
МенеджерЗаписи.Значение = ДанныеJSON.Value;
МенеджерЗаписи.Записать();
Возврат Новый HTTPСервисОтвет(200);
КонецФункции
Посмотрим на пример реализации «прокладки» с помощью PowerShell. Это мощный инструмент, который отлично взаимодействует с COM-объектами и позволяет отправлять HTTP-запросы без компиляции сложного ПО.
Проанализируем пример скрипта:
$comObject = New-Object -ComObject "ExternalSoftware.Application"
$eventCode = {
param($sender, $eventArgs)
$data = @{
EventName = "DataReceived"
Value = $sender.LastValue
} | ConvertTo-Json
Invoke-RestMethod -Uri "http://myserver/base/hs/events/v1" -Method Post -Body $data
}
Register-ObjectEvent -InputObject $comObject -EventName "OnNewData" -Action $eventCode
while($true) { Start-Sleep -Seconds 1 } # Удержание скрипта в памяти
Этот скрипт можно обернуть в службу Windows с помощью утилиты nssm или аналогичных средств. Это гарантирует, что обработка событий будет идти в фоновом режиме 24/7 без участия пользователя.
При переносе логики взаимодействия с COM на сторону сервера, мы неизбежно столкнемся с проблемами прав доступа. Выясним, что нужно настроить, чтобы сервер 1С мог работать с объектом.
Сервер 1С обычно запускается под технической учетной записью (например, USR1CV8). По умолчанию у этой записи нет прав на запуск и активацию многих COM-серверов. Разберем шаги по настройке:
dcomcnfg (Службы компонентов).USR1CV8 в разделы «Разрешения на запуск и активацию» и «Разрешения на доступ».Рассмотрим, какой метод выбрать в зависимости от условий:
Подводя итог, можно сказать, что напрямую «заставить» сервер 1С слушать COM-события через ДобавитьОбработчик невозможно в силу архитектуры Windows и самой платформы. Однако, используя событийную модель через внешние интерфейсы (HTTP/Web-сервисы), мы получаем гораздо более устойчивую и масштабируемую систему интеграции.