Поиск Web-сервисов — DISCO

Если у клиента имеется WSDL-контракт, описывающий Web-сервис, то у него есть вся информация для вызова этого Web-сервиса. Но после того, как вы сделали Web-сервис доступным, развернув его на Web-сервере, откуда клиенты возьмут WSDL-контракт? Более того, откуда клиенты вообще узнают о существовании вашего Web-сервиса?

Ответ состоит из двух частей: DISCO и UDDI (Universal Description, Discovery and Integration). Первый - это файловый механизм поиска локальных Web-сервисов, т.е. механизм получения списка доступных Web-сервисов из DISCO-файлов, размещенных на Web-серверах. Второй — это глобальный справочник Web-сервисов, который сам реализован как Web-сервис.

DISCO (сокращение от «discovery») – это простой протокол, работающий с DISCO-файлами в формате XML Основная идея в том, что вы на своем Web-сервере публикуете DISCO-файл, описывающий Web-сервисы, доступные на данном и, возможно, на других серверах. Клиенты могут обращаться к содержимому DISCO-файлов и отыскивать там сведения о том, какие Web-сервисы доступны и где находятся их WSDL-контракты. Например, вы создали два Web-сервиса с такими URL:

- http://www.wintellect.com/calc.asmx;

- http://www.wintellect.com/locator.asmx.

Чтобы объявить об их существовании, вы можете разместить следующий DISCO-файл по стандартному адресу на своем сервере. Элементы contractRef задают URL для WSDL-контрактов. URL могут быть абсолютными или относительными (относительно каталога, в котором находится DISCO-файл). Необязательные атрибуты docRef задают расположение документов, описывающих Web-сервисы, которые в связи с самодокументирующейся природой Web-сервисов, разработанных с помощью .NET Framework, обычно сами являются ASMX-файлами:

<?xml version="1.0" ?><discovery xmlns="http://schemas.xmlsoap.org/disco/" xmlns:scl="http://schemas.xmlsoap.org/disco/scl/"> <scl:contractRef ref="http://www.wintellect.com/calc.asmx?wsdl" docRef="http://www.wintellect.com/Calc.asmx" /> <scl:contractRef ref="http://www.wintellect.com/locator.asmx?wsdl" docRef="http://www.wintellect.com/Locator.asmx" /></discovery>

При желании можно писать отдельные DISCO-файлы для каждого Web-сервиса и помещать ссылки на них в главный DISCO-файл с помощью элементов discoveryRef. Вот пример DISCO-файла, ссылающегося на другие DISCO-файлы. Здесь URL также могут быть абсолютными или относительными:

<?xml version="1.0" ?><discovery xmlns="http://schemas.xmlsoap.org/disco/"> <discoveryRef ref="http://www.wintellect.com/calc.disco" /> <discoveryRef ref="http://www.wintellect.com/locator.disco" /></discovery>

Третий вариант — разместить VSDISCO-файл и использовать динамический поиск (dynamic discovery). Следующий VSDISCO-файл автоматически публикует все ASMX- и DISCO-файлы в данном каталоге и его подкаталогах, кроме подкаталогов, указанных элементами exclude.

<?xml version="1.0" ?><dynamicDiscovery xmlns="urn:schemas-dynamicdiscovery:disco.2000-03-17"> <exclude path="_vti_cnf" /> <exclude path="_vti_pvt" /> <exclude path="_vti_log" /> <exclude path="_vti_script" /> <exclude path="_vti_txt" /></dynamicDiscovery>

Как работает динамический поиск? ASP.NET отображает расширение имени файла .vsdisco на HTTP-обработчик, который отыскивает в данном каталоге и его подкаталогах файлы ASMX и DISCO и возвращает динамически генерируемый DISCO-документ. Клиент,обращающийся к VSDISCO-файлу, получает в ответ нечто, похожее на статический DISCO-файл.

По соображениям безопасности Microsoft отключила динамический поиск прямо перед выходом .NET Framework версии 1.0. Вы можете снова включить его, раскомментировав строку в разделе httpHandlers файла Machine.config, которая связывает .vsdisco с SystemWebSewicesDiscoveiyDiscoveryRequestHandler, и предоставив учетной записи ASPNET право доступа к метабазе IIS.

Чтобы еще больше упростить поиск Web-сервисов, вы можете поместить в домашний HTML-документ своего сайта ссылку на главный DISCO-файл. Допус­тим, например, что таким документом на www.wintellect.com является Default.htmlи в том же каталоге находится DISCO-документ Default.disco. Добавление следующего фрагмента в Dcfault.html позволит большинству инструментов, работающих с DISCO-файлами, принимать URL www.wintellect.com (в противоположность с www.wintellect.com/default.disco):

<html> <head> <link type="text/html" rel="alternate" href="Default.disco"> </head></html>

Visual Studio .NET ( а именно команда Add Web Reference) работает с DISCO-файлами, как и утилита Disco.exe из-NET Framework SDK.

Основной недостаток DISCO в том, что вы не можете считать DISCO-файл, если не знаете его URL. Так как же найти Web-сервис, если мы не знаем даже URL, с которого можно было бы начать? - U-D-D-I (ю-ди-ди-ай).

Поиск Web-сервисов — UDDI

UDDI — это сокращение от «Universal Description, Discovery, and Integration» («Универсальное описание, поиск и интеграция»). Разработанная совместно IBM, Microsoft и Ariba и поддерживаемая сотнями других компаний, она представляет собой спецификацию построения распределенных БД, которая позволяет отыскивать Web-сервисы. Эти БД никому не принадлежат, и каждый может опубликовать собственный реестр на основе UDDI. Сайты-операторы, уже организованные IBM и Microsoft, вероятно, будут первыми из множества подобных сайтов, которые появятся в будущем.

UDDI-сайты и сами являются Web-сервисами, Они предоставляет пару API на основе SOAP: API запросов для получения информации о компаниях и их Web-сервисах, а также API публикаций для объявления о доступности Web-сервисов компании. API запросов может использовать каждый, но к API публикаций сайты-операторы обычно позволяют обращаться только зарегистрированным членам. Сведения об этих API и другую информацию о UDDI см. по адресу http://www.uddi.org. Большинство разработчиков никогда не будет использовать API UDDI напрямую. Вместо этого для обращения к реестрам UDDI и генерации классов-оболочек для вызова найденных там Web-сервисов они будут применять инструменты высокого уровня, такие как Visual Studio .NET. Фактически непосредственно вызывать UDDI будут только разработчики инструментария, а также клиенты, которым нужно отыскивать Web-сервисы и подключаться к ним динамически.

Клиенты Web-сервисов

Теперь, когда мы подробно познакомились с Web-сервисами, пора заняться их клиентами, т. е. приложениями, которые используют или потребляют Web-методы. Web-сервисы писать легко. Написание их клиентов еще проще, благодаря наличию соответствующей высокоуровневой поддержки в библиотеке FCL и генератору кода Wsdl.exe. При наличии у вас WSDL-контракта, описывающего Web-сервис (или URL DISCO-файла, ссылающегося на WSDL-контракт), вы сможете вызывать его практически сразу.

Прокси Web-сервисов

Основная концепция, с которой нужно быть знакомым для написания клиентов Web-серисов, — это прокси Web-сервиса. Прокси Web-сервиса — это объект, который является локальным представлением удаленного Web-сервиса. Экземпляр прокси создается в домене приложения клиента, но вызовы прокси передаются последним Web-сервису, который он представляет. Утилита Wsdl.exe, поставляемая в составе .NET Framework SDK (и интегрированная в Visual Studio .NET), генерирует прокси-классы Web-сервисов на основе WSDL-контрактов. После создания прокси вызов соответствующего Web-сервиса — это просто вызов методов прокси:

CalculatorWebService calc = new CalculatorWebService ();Int sum = calc.Add(2,2);

Методы прокси-класса соответствуют Web-методам Web-сервиса. Если Web-сервис предоставляет методы Add и Subtract, то и его прокси также содержит их. При вызове любого из этих методов прокси упаковывает входные параметры и вызывает Web-метод, по протоколу, инкапсулированному в прокси (обычно это SOAP). Прокси изолирует вас от низкоуровневых деталей Web-сервиса и используемых им протоколов. Он даже выполняет разбор XML, возвращенного Web-сервисом, и преобразует результаты в управляемые типы данных.

Сгенерировать прокси Web-сервиса с помощью Wsdl.exe очень просто. Допустим, нужно вызвать Web-сервис, URL которого http://www.wintenect.com/calc.asmx. Если Web-сервис написан с помощью .NET Framework, т. е. WSDL-контракт можно получить, добавив строку запроса «?wsdl» к URL сервиса, то сгенерировать прокси для этого сервиса можно так:

wsdl http://www.wintellect.com/calc.asmx?wsdl

Или вы можете опустить строку запроса, и Wsdl.exe подставит ее за вас:

wsdl http://www.wintellect.com/calc.asmx

Если при написании Calc.asmx .NET Framework не использовалась, то он может и не поддерживать строки запроса WSDL. Тогда вам нужно самому отыскать WSDL-контракт и передать Wsdl.exe его URL (или локальное путевое имя). В следующем примере предполагается, что контракт находится в локальном файле Calc.wsdb

Wsdl calc.wsdl

Независимо от способа указания WSDL-контракта, Wsdl.exe генерирует CS-файл, содержащий класс, представляющий собой прокси Web-сервиса. Экземпляр именно этого класса вы должны создать для вызова методов Web-сервиса.

Имя класса образуется по имени сервиса (т. е. по атрибуту пате элемента service) в WSDL-контракте. Например, допустим, что в файле ASMX Web-сервиса содержится атрибут:

[WebService (Name="Calculator Web Service")]

В результате WSDL-контракт будет содержать тэг:

<service name="Calculator Web Service">

а именем класса прокси будет CalculatorWebService. По умолчанию имя CS-файла, который генерирует Wsdl.exe, также получается из имени сервиса (например, Calculator Web Service.cs). Вы можете задать другое имя через параметр /out командной строки Wsdl.exe. Команда:

wsdl /out: Calc.cs http://www.wintellect.com/calc.asmx

генерирует файл Calc.cs независимо от имени сервиса.

Wsdl.exe поддерживает много параметров командной строки, с помощью которых вы можете влиять на результаты ее работы. Так, если вы хотите, чтобы класс прокси был не на С#, а не Visual Basic .NET, задайте параметр /language.

wsdl /language:vb http://www.wintellect.com/calc.asmx

Если нужно, чтобы Wsdl.exe поместил генерируемый им код в пространство имен (это очень полезная возможность для предотвращения коллизии имен между ти­пами в сгенерированном коде и типами, определенными в вашем приложении или в FCL), определите параметр /namespace-.

wsdl /namespace:Calc http://www.wintellect.com/calc.asmx

Wsdl.exe генерирует классы, производные от базовых классов из пространства имен FCL SystemWebServicesProtocols. По умолчанию базовым для класса прокси будет SoapHttpCHentProtocol, который позволяет использовать для вызова Web-методов SOAP поверх HTTP. Параметр командной строки /protocol позволяет задать другой протокол вызова. Команда:

wsdl /protocol:httpget http://www.wintellect.com/calc.asmx

создает прокси, являющийся производным от HttpGetCHentProtocol и вызывающий Web-методы с помощью HTTP-команд GET, тогда как команда:

wsdl /protocol:httppost http://www.wintellect.com/calc.asmx

создает прокси, являющийся производным от HttpPostCtientProtocol и вызывающий Web-методы с помощью HTTP POST. Зачем изменять протокол, используемый классом прокси для вызова Web-методов? Обычно SOAP прекрасно подходит. Если же вызываемые вами методы – это простые методы, использующие столь же простые типы, то HTTP GET или POST немного повышают эффективность вызовов за счет сокращения объема данных, пересылаемых по сети.

Поиск Web-сервисов — DISCO - student2.ru Кстати, если вы пишете клиенты Web-сервисов с помощью Visual Studio .NET, запускать Wsdl.exe вручную не нужно. При вызове команды Add Web Reference, расположенной в меню Project (в среде Visual Studio 2003) или Website (в среде Visual Studio 2005), Visual Studio .NET запускает Wsdl.exe автоматически и добавляет класс прокси в ваш проект. Add Web Reference также понимает UDDI, что позволяет легко отыскивать нужные Web-сервисы в UDDI-реестре Microsoft.

Наши рекомендации