При интеграции 1С с внешними SOAP веб-сервисами с использованием устаревшей библиотеки MSSOAP.SoapClient30 разработчики часто сталкиваются с ошибкой инициализации COM-соединения при переносе рабочего кода на сервер. Разберем причины возникновения этой проблемы и рассмотрим подробные варианты ее устранения.
Типичный текст ошибки в журнале регистрации или окне сообщений выглядит следующим образом:
{ОбщийМодуль.МодульРегламентныхЗаданий.Модуль(277)}: Ошибка при вызове конструктора (COMОбъект)
Клиент = Новый COMОбъект("MSSOAP.SoapClient30");
по причине:
-2146959355(0x80080005): Ошибка при выполнении приложения-сервера
Проанализируем архитектурные особенности работы COM-компонентов в среде Windows Server и платформы 1С:
MSSOAP30.dll и msscript.ocx (компонент MSScriptControl.ScriptControl) существуют исключительно в 32-разрядном исполнении. 64-битный рабочий процесс сервера 1С:Предприятия (rphost.exe) не может загрузить 32-битные DLL напрямую в собственное адресное пространство.USR1CV8) без предварительно настроенного суррогатного процесса dllhost.exe операционная система возвращает ошибку 0x80080005 (CO_E_SERVER_EXEC_FAILURE).Разберем по шагам, как заставить 32-разрядный COM-компонент корректно работать в 64-битной операционной системе и сервере 1С:
dcomcnfg в командной строке).SoapClient30_x86) и укажем тип активации Серверное приложение (Server Application).USR1CV8).C:\Program Files (x86)\Common Files\MSSoap\Binaries\MSSOAP30.dll.msscript.ocx из папки C:\Windows\SysWOW64\, если в программном коде используется MSScriptControl.ScriptControl.Посмотрим на типовой пример кода 1С, который работает с данным COM-объектом после правильной настройки суррогата:
Клиент = Новый COMОбъект("MSSOAP.SoapClient30");
Если ПустаяСтрока(ПространствоИмен) Тогда
Клиент.MSSoapInit(АдресWSDL, ИмяСервиса, ИмяПорта);
Иначе
Клиент.MSSoapInit2(АдресWSDL, "", ИмяСервиса, ИмяПорта, ПространствоИмен);
КонецЕсли;
// Установка параметров соединения через оболочку VBScript
Оболочка = Новый COMОбъект("MSScriptControl.ScriptControl");
Оболочка.Language = "vbscript";
Оболочка.AddCode("
|Sub SETConnectorProperty(Client, PropertyName, PropertyValue)
| Client.ConnectorProperty(PropertyName) = PropertyValue
|End Sub
|Sub SETClientProperty(Client, PropertyName, PropertyValue)
| Client.ClientProperty(PropertyName) = PropertyValue
|End Sub
|");
Оболочка.Run("SETConnectorProperty", Клиент, "Timeout", 30000);
Использование MSSOAP.SoapClient30 и MSScriptControl несет архитектурные риски: библиотеки сняты с поддержки производителем, создают нестабильность при вызове через dllhost.exe и не работают на Linux-серверах 1С. Встроенные средства платформы 1С позволяют выполнять любые SOAP-запросы напрямую через протокол HTTP.
Разберем, как реализовать прямой SOAP-запрос с помощью объектов HTTPСоединение и HTTPЗапрос:
// Формируем тело SOAP-конверта (Envelope)
ТелоЗапросаXML =
"<?xml version=""1.0"" encoding=""utf-8""?>
|<soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance""
| xmlns:xsd=""http://www.w3.org/2001/XMLSchema""
| xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
| <soap:Body>
| <GetItemsList xmlns=""http://tempuri.org/"">
| <ItemCode>12345</ItemCode>
| </GetItemsList>
| </soap:Body>
|</soap:Envelope>";
// Настраиваем соединение с сервером
Сервер = "api.service.ru";
Порт = 443;
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
Соединение = Новый HTTPСоединение(Сервер, Порт, , , , 30, ЗащищенноеСоединение);
// Подготавливаем заголовки запроса
Заголовки = Новый Соответствие();
Заголовки.Вставить("Content-Type", "text/xml; charset=utf-8");
Заголовки.Вставить("SOAPAction", "http://tempuri.org/GetItemsList");
// Создаем и отправляем HTTP-запрос
Запрос = Новый HTTPЗапрос("/soap/service.asmx", Заголовки);
Запрос.УстановитьТелоИзСтроки(ТелоЗапросаXML, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
Если Ответ.КодСостояния = 200 Тогда
СтрокаОтветаXML = Ответ.ПолучитьТелоКакСтроку();
// Обрабатываем полученный XML с помощью ЧтениеXML или ПостроительDOM
Чтение = Новый ЧтениеXML();
Чтение.УстановитьСтроку(СтрокаОтветаXML);
Построитель = Новый ПостроительDOM();
ДокументDOM = Построитель.Прочитать(Чтение);
// Извлекаем полезные данные из DOM-модели
Иначе
ВызватьИсключение "Ошибка выполнения SOAP-запроса: " + Ответ.КодСостояния;
КонецЕсли;
Переход на нативные механизмы платформы 1С (HTTPСоединение, ЗаписьXML, ПостроительDOM) полностью исключает зависимость от операционной системы, разрядности сервера и настроек COM+.