Веб-сервисы и 1С: «Здравствуй, Name», время-деньги и «Жизнь»




Несколько статей о создании веб-сервисов на платформе 1С

Веб-сервисы и 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

Продолжение в следующей части.

11 Comments

  1. Makushimo

    ну вот.. на самом интересном месте!

    Reply
  2. alexburn

    Когда теперь ожидать продолжение ?

    Reply
  3. kolya_tlt

    Спасибо за статейку. в качестве пожелания: добавьте информацию из БСП, там нет уже готовых процедур по сборке wsdl и ws? добавьте проверки. прокси может не определиться, метода может вдруг не оказаться, нужное поле может тоже пропасть. также стандарт требует наличие Пинга.

    https://its.1c.ru/db/v8std#content:-2145782899:hdoc

    Reply
  4. docerman

    Отличная статья. Простое объяснение. Тоже жду продолжения. Веб-сервисы для чайников).

    Reply
  5. kiv1c

    (1) я в своей статье тоже рассматривал построение веб-сервисов с нуля

    http://infostart.ru/public/537861/

    Reply
  6. hayroff

    (2) надеюсь, в ближайшие пару дней.

    Reply
  7. hayroff

    (3) Спасибо. Да, вы правы, в БСП есть конструктор «СоздатьWSПрокси» в общем модуле «ОбщегоНазначения».

    Reply
  8. tiger12

    После публикации веб-сервиса и перехода по строке в браузере http://localhost/WebServices/ws/1c_wstest.1cws?wsdl

    выходит

    <soap:Envelope xmlns:soap=»http://schemas.xmlsoap.org/soap/envelope/»>

    <soap:Body>

    <soap:Fault>

    <faultcode>soap:Client</faultcode>

    <faultstring>

    Ошибка вызова операции сервиса: {http://localhost/WebServices/}:WebServiceTest:getWSDL() по причине: Ошибка инициализации библиотеки модулей по причине: {WebСервис.WebServiceTest.Модуль(3,38)}: Переменная не определена (Name)

    </faultstring>

    <detail/>

    </soap:Fault>

    </soap:Body>

    </soap:Envelope>

    Reply
  9. hayroff

    Скорее всего вы забыли добавить параметр Name операции как объект метаданных. На рисунке 2 он выглядит как дочерний узел опрации в виде зеленого шарика.

    Reply
  10. hayroff

    (3) Пинг является не обязательной, а рекомендованной операцией для сервисом с таймаутом > 20 сек.

    Даже в стандартных сервисах БСП он присутствует не во всех сервисах, или выполнен в виде заглушки.

    Reply
  11. Dream_kz

    Позвольте возразить,

    Минус файловой версии — невозможность отладки серверных процедур.

    с сервером отладки по http можно отладить хоть фоновые задания с мобильными приложениями.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *