Веб-сервисы и 1С: «Здравствуй, Name», время-деньги и «Жизнь»
«Вся наша жизнь — игра…» ( У. Шекспир)
«Что наша жизнь? Игра…» (А. Пушкин)
Часть вводная.
При разработке приложений с глобальным взаимодействием уже давно известна архитектура SOA (Service Oriented Architecture).
Такая архитектура подразумевает, что приложения на разных платформах, в разных средах взаимодействуют между собой, при этом разработчик может не беспокоиться о том, что находится внутри приложений на той стороне (т.е. об их реализации) , а также о том, что находится снаружи их (т.е. об их среде окружения).
Существует достаточно большое количество реализации этой архитектуры. Одним из видов такой реализации является технология основанная на связке специфицированных консорциумом w3c таких технологий, как веб-сервисы и протоколы SOAP, WSDL, WADL и т.п., которые в свою очередь основаны на XML. Уже достаточно длительное время эта технология интегрирована в платформу 1с Предприятие. Благодаря этому 1с предприятие может служить «сервером приложений», поставщиком сервисов, можно организовать взаимодействие между 1с, и приложениями, написанными на других платформах, можно организовать взаимодействие между различными системами на базе 1с и так далее.
Существует достаточно большое количество полезных web-сервисов, например: получение курсов валют, службы отправки почтовых сообщений и SMS на основе
web-сервисов и WSDL, каковую архитектуру используют туристические агентства, гостиницы, ритейлеры и т.п.
Часть 1. Здравствуй, Name!
Есть достаточное количество противников SOA и сторонников других технологий, как и тех, кто недолюбливает 1С. Однако существующая технология разработки на платформе 1с позволяет приступить к разработке и получить готовый результат довольно быстро при весьма поверхностном знакомстве с подробностями спецификаций SOA, WSDL и веб-сервисов, по сравнению со многими другими известными продуктами как от гигантов софтверной индустрии, так и с бесплатными open-source решениями, что само по себе не является ни плюсом ни минусом, но может заставить задуматься.
Чтобы окончательно в этом убедиться я твердо решил в качестве примера реализовать при помощи web-сервисов хрестоматийный пример, на котором большинство студентов, изучавших вычислительную технику и программирование, практиковались ещё во время учебы в ВУЗ-ах, а именно игру «Жизнь» — клеточный автомат, придуманный английским математиком Джоном Конвеем в 1970 г.
Но не сразу, а постепенно, для начала, чтобы просто понять, как это работает, создадим простой веб-сервис, который будет иметь выполнять одну операцию с одним параметром строкового типа и будет возвращать тоже строку.
Для начала надо всё же установить веб-сервер, который будет обрабатывать запросы, это может быть Apache или IIS. Я предпочитаю Apache. Поскольку The Apache HTTP Server Project
предоставляет только исходники своего продукта, воспользуемся скомпилированной версией
от Apache House. (это обязательно должна быть 32-разрядная версия, веб-расширение 1С не работает с 64-разрядной)
Загрузив архив, распакуем его куда-нибудь, например, в корневой каталог. Далее, установим веб-сервер в качестве сервиса, запустив сервер из командной строки с параметром -k install, вот так:
c:Apache24inhttpd.exe -k install
Теперь нам нужно также:
-
создать в каталоге веб-документов каталог для публикации наших сревисов
-
установить web-расширение 1c-Предприятия
-
создать и опубликовать первый веб-сервис
Каталог для публикации должен быть расположен в каталоге c:Apache24htdocs.
Назовем его WebServices.
Теперь откроем панель управления: Панель управленияПрограммыПрограммы и компоненты, выберем нужную версию программы 1с-Предприятие, нужно будет нажать правую кнопку и выбрать пункт «Изменить», затем «Изменить-Далее» и выбрать в списке
«Модули расширения Веб-сервера» (Web server extention modules) — рис1
Рис1
Теперь создадим пустую файловую базу, в ней роль «Полная» с полными правами на все группы объектов и пользователя Admin, назначив ему эту единственную роль.
На вопрос, будет ли это работать в файловом варианте — ответ положительный (во всяком случае этот простой пример работает как файловая база).
Минус файловой версии — невозможность отладки серверных процедур.
Теперь приступим к реализации. В группе web-сервисы создадим новый объект с простым именем WebServiceTest, операцией с именем GetHelloString, которую будет обрабатывать функция Привет(Name) и параметром Name. И операция и параметр добавляются командой «добавить». Тип значения параметра Name — string (берется из пространства имен
http://www.w3.org/2001/XMLSchema)
URI пространства имен для сервиса указываем равный каталогу нашей публикации на веб-сервере — http://localhost/WebServices/
имя файла публикации может быть любым, но желательно латинским шрифтом и обязательно с расширением 1cws. Все вместе это выглядит так (Рис. 2):
Рис. 2
Тело функции Привет() модуля сервиса будет содержать только одну строку:
Функция Привет(Name)
Возврат("Здравствуй, дорогой друг "+Name+"!");
КонецФункции
Осталось только опубликовать сервис. Заходим в меню администрирование -> публикация на web-сервере. Откроется форма, в которую мы введем параметры публикации. Имя публикации должно совпадать с именем каталога на web-сервере.
В поле «Каталог» вводим путь к нашему каталогу на web-сервере, который мы создали ранее, то есть C:Apache24htdocsWebServices
Остальные параметры вы можете рассмотреть на рисунке Рис. 3
Рис. 3
перезапустим web-сервер, используя Apache monitor (оснастку служб Windows, закладку «службы» диспетчера задач, командную строку, bash, монитор процессов — что там у вас есть под рукой) чтобы данные публикации были считаны Апачем заново. Обновление публикации и перезапуск веб-сервера нужно делать после каждого сохранения конфигурации, связанного с изменениями веб-сервиса.
Осталось только протестировать нашу веб-службу. Для этого наберем в строке браузера http://localhost/WebServices/ws/1c_wstest.1cws?wsdl
или
https://localhost/WebServices/ws/1c_wstest.1cws?wsdl
Результат должен выглядеть как-то так:
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap12bind="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:soapbind="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://localhost/WebServices/" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsd1="http://localhost/WebServices/" name="WebServiceTest" targetNamespace="http://localhost/WebServices/">
<types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xs1="http://localhost/WebServices/" targetNamespace="http://localhost/WebServices/" elementFormDefault="qualified">
<xs:element name="GetHelloString">
<xs:complexType>
<xs:sequence>
<xs:element name="Name" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="GetHelloStringResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="return" type="xs:string"/>
<xs:element name="Name" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
</types>
<message name="GetHelloStringRequestMessage">
<part name="parameters" element="tns:GetHelloString"/>
</message>
<message name="GetHelloStringResponseMessage">
<part name="parameters" element="tns:GetHelloStringResponse"/>
</message>
<portType name="WebServiceTestPortType">
<operation name="GetHelloString">
<input message="tns:GetHelloStringRequestMessage"/>
<output message="tns:GetHelloStringResponseMessage"/>
</operation>
</portType>
<binding name="WebServiceTestSoapBinding" type="tns:WebServiceTestPortType">
<soapbind:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="GetHelloString">
<soapbind:operation style="document" soapAction="http://localhost/WebServices/#WebServiceTest:GetHelloString"/>
<input>
<soapbind:body use="literal"/>
</input>
<output>
<soapbind:body use="literal"/>
</output>
</operation>
</binding>
<binding name="WebServiceTestSoap12Binding" type="tns:WebServiceTestPortType">
<soap12bind:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="GetHelloString">
<soap12bind:operation style="document" soapAction="http://localhost/WebServices/#WebServiceTest:GetHelloString"/>
<input>
<soap12bind:body use="literal"/>
</input>
<output>
<soap12bind:body use="literal"/>
</output>
</operation>
</binding>
<service name="WebServiceTest">
<port name="WebServiceTestSoap" binding="tns:WebServiceTestSoapBinding">
<documentation>
<wsi:Claim xmlns:wsi="http://ws-i.org/schemas/conformanceClaim/" conformsTo="http://ws-i.org/profiles/basic/1.1"/>
</documentation>
<soapbind:address location="https://localhost/WebServices/ws/1c_wstest.1cws"/>
</port>
<port name="WebServiceTestSoap12" binding="tns:WebServiceTestSoap12Binding">
<soap12bind:address location="https://localhost/WebServices/ws/1c_wstest.1cws"/>
</port>
</service>
</definitions>
Клиентская часть будет содержать чуть больше кода. Можно обращаться к сторонним сервисам двумя способами:
— использовать ws-ссылку (объект метаданных)
— создать ws-определение программно
Первый способ означает, что нам нужна ещё одна конфигурация, поэтому сейчас используем второй. Разница лишь в том, что мы создадим объект программно.
Создадим новую обработку с реквизитом Name, разместим его на форме, добавим форме команду Тест с двумя поцедурами, на клиенте и на сервере.
&НаСервере
Процедура ТестНаСервере()
ссл = Новый ЗащищенноеСоединениеOpenSSL;
всОпред = Новый WSОпределения("http://localhost/WebServices/ws/1c_wstest.1cws?wsdl","Admin","123",,,ссл);
всПрокси = Новый WSПрокси(всОпред, "http://localhost/WebServices/", "WebServiceTest", "WebServiceTestSoap",,,ссл);
всПрокси.Пользователь="Admin";
всПрокси.Пароль="123";
пакет = всПрокси.ФабрикаXDTO.Пакеты.Получить("http://www.w3.org/2001/XMLSchema");
типВС_Параметра = пакет.Получить("Name");
пИмя = ?(ЗначениеЗаполнено(Объект.Имя), Объект.Имя, "Name"); //передаваемая Строка должна быть непустая
всПараметр = всПрокси.ФабрикаXDTO.Создать(типВС_Параметра, пИмя);
Значение = всПрокси.GetHelloString(всПараметр);
Сообщить(Значение);
КонецПроцедуры
&НаКлиенте
Процедура Тест(Команда)
ТестНаСервере();
КонецПроцедуры
Параметры конструктора объекта WSПрокси ИмяСервиса и ИмяТочкиПодключения можно найти в XML-тексте, который возвращает наш сервис по URI https://localhost/WebServices/ws/1c_wstest.1cws?wsdl
А именно в элементе <service name=»ИмяНашегоСервиса»>
где ИмяСервиса — это атрибут Name этого элемента, то есть <service name=»WebServiceTest»>
ИмяТочкиПодключения — это атрибуты Name вложенных элементов
<port><port/>
Обычно мы имеем две точки для разных версий SOAP, в нашем случае они называются
WebServiceTestSoap и WebServiceTestSoap12 — можно использовать любой из них.
Сохраняем изменения в обработке, открываем её в любой базе и тестируем. Результат — вывод сообщения возвращенной операцией нашего удаленного сервиса строки. (Рис. 4)
Рис. 4
Продолжение в следующей части.
ну вот.. на самом интересном месте!
Когда теперь ожидать продолжение ?
Спасибо за статейку. в качестве пожелания: добавьте информацию из БСП, там нет уже готовых процедур по сборке wsdl и ws? добавьте проверки. прокси может не определиться, метода может вдруг не оказаться, нужное поле может тоже пропасть. также стандарт требует наличие Пинга.
Отличная статья. Простое объяснение. Тоже жду продолжения. Веб-сервисы для чайников).
(1) я в своей статье тоже рассматривал построение веб-сервисов с нуля
http://infostart.ru/public/537861/
(2) надеюсь, в ближайшие пару дней.
(3) Спасибо. Да, вы правы, в БСП есть конструктор «СоздатьWSПрокси» в общем модуле «ОбщегоНазначения».
После публикации веб-сервиса и перехода по строке в браузереhttp://localhost/WebServices/ws/1c_wstest.1cws?wsdl
выходит
<soap:Envelope xmlns:soap=»http://schemas.xmlsoap.org/soap/envelope/»>
http://localhost/WebServices/ }:WebServiceTest:getWSDL() по причине: Ошибка инициализации библиотеки модулей по причине: {WebСервис.WebServiceTest.Модуль(3,38)}: Переменная не определена (Name)
<soap:Body>
<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>
Ошибка вызова операции сервиса: {
</faultstring>
<detail/>
</soap:Fault>
</soap:Body>
</soap:Envelope>
Скорее всего вы забыли добавить параметр Name операции как объект метаданных. На рисунке 2 он выглядит как дочерний узел опрации в виде зеленого шарика.
(3) Пинг является не обязательной, а рекомендованной операцией для сервисом с таймаутом > 20 сек.
Даже в стандартных сервисах БСП он присутствует не во всех сервисах, или выполнен в виде заглушки.
Позвольте возразить,
с сервером отладки по http можно отладить хоть фоновые задания с мобильными приложениями.