ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 29.10.2023
Просмотров: 26
Скачиваний: 1
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
Лабораторная работа № 1.
SOAP: доступ к сервисам
-
Цель.
Научиться работать с Web-сервисами (на примере и посредством протокола SOAP).
Для демонстрации работы с Web-службами мы будем использовать открытый Web-сервис Центрального банка Российской Федерации, предоставляющий актуальные данные Центробанка, в частности о ставкерефинансирования, золотовалютных резервы, денежной базе, денежной массе, валютном свопе buy/sell и т.д. Мы будем получать текущий курс нужной валюты.
-
Обеспечение
MS Visual Studio 12(13)
Доступ в Интернет
-
Что делать
-
Создаем проект WPF (мы будем использовать особенности WPFпри реализации пользовательского интерфейса).
Рис.1. Создание проекта.
-
Добавляем ссылку на SOAP-сервис, который нам требуется использовать (щелчком правой кнопки мыши в «Обозревателе решений» вызываем Добавить (Add)\Ссылку на службу (AddServiceReference). В появившемся окне нажимаем «Дополнительно». В появившемся окне нажимаем «Добавить Web-ссылку», в следующем окне в поле URL-Адрес вводим http://www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx?WSDL и нажимаем кнопку «Перейти». После успешного перехода (это будет выглядеть как на рис.2) нажимаем кнопку «Добавить ссылку».
Что происходит в этот момент: с введенного адреса скачивается WSDL-файл, содержащий спецификацию структуры и поведения сервиса, который мы собираемся использовать, в частности определение вида отправляемых и получаемых веб-сервисом сообщений (types), сами сообщения, используемые веб-сервисом (messages), операции, которые могут быть выполнены с сообщениями (portType) и способы доставки сообщений (binding). На основе файлаWSDLсоздается прокси-класс (или классы) для обращения к сервису.
Рис. 2. Добавление веб-ссылки.
| |
Рис. 3. Фрагмент WSDL-спецификации и соответствующего обработчика ссылки на службу.
-
Создаем класс, который в пределах нашего приложения будет являться информационным экспертом по предоставлению ежедневных данных Центробанка. Оснастим его свойством, отвечающим за доступ к Веб-сервису. Основной интерфейс, посредством которого осуществляются все обращения в WSDLи, соответственно, в обозревателе объектов VSназывается DailyInfo.
publicclassCBRService
{
private CBR.DailyInfo _cbrClient;
// обеспечивает доступ к веб-сервису
public CBR.DailyInfo Cbr
{
get
{
if (_cbrClient == null)
{
_cbrClient = newDailyInfo();
}
return _cbrClient;
}
}
-
Далее нам требуется обратиться к созданному экземпляру DailyInfo за сведениями (в нашем случае это курс выбранной валюты на дату), получить эти сведения и расшифровать их. Спецификация интересующего нас метода в документации к веб-сервису (http://www.cbr.ru/scripts/Root.asp?PrtId=DWS) выглядит так.
Соответственно мы 1) определяем приватный статический методаExtractCurrencyRate, осуществляющего разбор XML-таблицы; 2) определяем метод запроса данных GetCurrencyRateOnDate, передающего полученный от DailyInfoDataSetв метод разбора.
При определении сигнатуры методов обратите внимание, что метод GetCursOnDate возвращает курсы всех валют, на дату, а мы хотим получать курс выбранной валюты указав её символьный код.
-
Реализуем наши методы (ниже приведен код ExtractCurrencyRate, написание заглушек, а также реализацию для первого метода следует сделать самостоятельно).
{
if (ds == null)
thrownewArgumentNullException("ds", "Параметр ds неможетбыть null.");
if (string.IsNullOrEmpty(currencyCode))
thrownewArgumentNullException("currencyCode", "Параметр currencyCode неможетбыть null.");
DataTable dt = ds.Tables["ValuteCursOnDate"];
DataRow[] rows = dt.Select(string.Format("VchCode=\'{0}\'", currencyCode));
if (rows.Length > 0)
{
decimal result;
if (decimal.TryParse(rows[0]["Vcurs"].ToString(), out result))
return result;
thrownewInvalidCastException("От службы ожидалось значение курса валют.");
}
thrownewKeyNotFoundException("Для заданной валюты не найден курс.");
}
-
Можно вызвать созданный метод. Несмотря на то, что проект WPFи настраивает на несколько другой образ действий, поступим по старинке: разместим на форме текстовый блок и кнопку, добавим кнопке обработчик нажатия, который будет отображать результат GetCurrencyRateOnDate в текстовом блоке.
К сожалению, документация о наименованиях валют на сайте ЦБР не актуальна, но текстовый код нужной валюты можно посмотреть, добавив в качестве контрольного значения переменную dt.
-
Можно заметить, что во время запроса наша нехитрая программа не отвечает («подвисает» - более привычное выражение).
Чтобы от этого избежать надо сделать наш вызов асинхронным. При данном типе взаимодействия потребитель сервиса не ждет окончания обработки запроса поставщиком сервиса, а сразу после получения уведомления о принятии данного запроса к обработке продолжает свою работу. Существует два подхода к обеспечению асинхронного взаимодействия с помощью механизма веб-сервисов:
- полинг - повторяющийся опрос (потребитель сервиса периодически запрашивает у поставщика статус и результат обработки запроса);
- обратный вызов (поставщик сервиса после завершения обработки запроса уведомляет потребителя, вызывая специальный метод).
Мы будем реализовыветь обратный вызов, тем более, что инструмент генерации прокси-класса на основе WSDLобеспечил нас этим способом асинхронного взаимодействия. Мы видим в обозревателе объектов класс GetCursOnDateCompletedEventArgsи событие-делегат GetCursOnDateCompleted, а в числе методов прокси-класса DailyInfoметод GetCursOnDateAsync.
-
Создаем метод, который будет инициировать на веб-сервисе начало асинхронной операции.
publicvoid AsyncGetCurrencyRateOnDate(DateTime dateTime, string currencyCode)
{
Cbr.GetCursOnDateAsync(dateTime, currencyCode);
}
9.Создаемобработчиксобытия, чтобыподписатьсяназавершениеполучениякурсавалюты.В этом обработчике курс возвращается в предварительно созданное нами свойство LastQueriedRateдоступное для чтения/записи.
void _cbrClient_GetCursOnDateCompleted(object sender, GetCursOnDateCompletedEventArgs e)
{
LastQueriedRate = ExtractCurrencyRate(e.Result, (string)e.UserState);
}
10. А теперь непосредственно подписка, она производится сразу после экземпляра прокси-класса (возвращаемся к коду, написанному на шаге 3 и добавляем подписку на событие).
_cbrClient.GetCursOnDateCompleted += newGetCursOnDateCompletedEventHandler(_cbrClient_GetCursOnDateCompleted);
11. Немного отклоняясь от основной темы, проиллюстрируем работу модели MVVMв сочетании с WPF. У нас на форме есть текстовый блок и кнопка с обработчиком нажатия. Изменим обработчик, таким образом чтобы теперь он вызывал наш новый, асинхронный метод.
12. В конструкторе главного окна зададим контекст данных - объект
, значения свойств которого могут автоматически привязываться к интерфейсным элементам этой формы (такая привязка называется Binding).
CBRService cbr = newCBRService();
public MainWindow()
{
InitializeComponent();
DataContext = cbr;
}
13. Изменим XAML-код формы, так чтобы значение свойства текст для текстового блока было связано с последним запрошенным курсом валюты из CBRService.
14. Научим наш сервис уведомлять своих клиентов об изменении значений свойств. Для этого добавим к его списку наследования/реализации интерфейсINotifyPropertyChanged.Интерфейс INotifyPropertyChanged используется для уведомления клиентов, обычно клиентов – участников привязки, об изменении значения свойства.
publiceventPropertyChangedEventHandler PropertyChanged;
privatevoid NotifyPropertyChanged(String propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, newPropertyChangedEventArgs(propertyName));
}
}
15. Изменим метод записи свойства LastQueriedRate таким образом, чтобы при изменении значения этого свойства вызывался метод NotifyPropertyChanged.
set
{
if (lastQueriedRate == value) return;
lastQueriedRate = value;
NotifyPropertyChanged("LastQueriedRate");
}
16. Запускаем программу и смотрим. Она немного приостанавливается в момент вызова, но не так надолго как при синхронном вызове.
-
Что делать, если закончили.
-
Поискать в спецификации методов на сайте ЦБР способ получить от сервиса текстовые обозначения валют. Видоизменить программу таким образом, чтобы она возвращала курс выбранной валюты на выбранную пользователем дату. -
Замерить время работы асинхронного и синхронного метода ( «подвисание» при асинхронном вызове связано со временем, требующимся на разбор данных полученных от сервиса). -
Реализовать возврат значения CBRService при асинхронном вызове без использования INotifyPropertyChanged, через стандартный механизм событий. -
Реализовать при этом обработку исключений с доставкой данных об исключении совершившему асинхронный вызов клиенту.
-
Связанныеопределения.
Удалённый вызов процедур (Remote Procedure Call (RPC)) — класс технологий, позволяющих компьютерным программам вызывать функции или процедуры в другом адресном пространстве (как правило, на удалённых компьютерах). Обычно, реализация RPC технологии включает в себя два компонента: сетевой протокол для обмена в режиме клиент-сервер и язык сериализации объектов (или структур, для необъектных RPC).
Сервис-ориентированная архитектура — модульный подход к разработке программного обеспечения, основанный на использовании распределённых, слабо связанных заменяемых компонентов, оснащённых стандартизированными интерфейсами для взаимодействия по стандартизированным протоколам.Программные комплексы, разработанные в соответствии с сервис-ориентированной архитектурой, обычно реализуются как набор веб-служб.
Веб-служба, веб-сервис — идентифицируемая веб-адресом программная система со стандартизированными интерфейсами.
XML-RPC (сокр. от англ. Extensible Markup Language Remote Procedure Call — XML-вызов удалённых процедур) — стандарт/протокол вызова удалённых процедур, использующий XML для кодирования своих сообщений и HTTP в качестве транспортного механизма. XML-RPC, как и любой другой интерфейс Remote Procedure Call (RPC), определяет набор стандартных типов данных и команд.
SOAP — протокол обмена структурированными сообщениями в формате XML в распределённой вычислительной среде. SOAP является расширением протокола XML-RPC.
Пример SOAP-запроса [https://ru.wikipedia.org/wiki/SOAP]:
12345
Примерответа:
12345
Стаканграненый
9.95
840
WSDL (англ. Web Services Description Language) — язык описания веб-сервисов и доступа к ним, основанный на языке XML.
Прокси(Proxy)-класс – класс-заместитель, который контролирует доступ к другому классу перехватывая все вызовы или выполняя функцию контейнера.
Источники
https://www.oasis-open.org/committees/download.php/19679/soa-rm-cs.pdf
http://www.w3.org/TR/soap/
http://xmlrpc.scripting.com/default.html
http://habrahabr.ru/post/131343/
http://habrahabr.ru/post/134303/