В Сети существует много разных ресурсов, которые предоставляют пользователям определенную информацию. Имеются в виду не обычные статические страницы, а, к примеру, данные, извлекаемые из базы данных или архивов. Это может быть архив финансовых данных (курсы валют, данные котировок ценных бумаг), данные о погоде, или же более объемная информация — новости, статьи, сообщения из форумов. Такая информация может представляться посетителю страницы, к примеру, через форму, как ответ на запрос, или же каждый раз генерироваться динамически. Но трудность в том, что часто такая информация нужна не столько конечному пользователю — человеку, сколько другим системам, программам, которые эти данные будут использовать для своих расчетов или других потребностей.
Реальный пример: страница банковского сайта, на которой показываются котировки валют. Если вы заходите на страницу как обычный пользователь, через браузер, вы видите все оформление страницы, баннеры, меню и другую информацию, которая «обрамляет» истинную цель поиска — котировки валют. Если вам надо вносить эти котировки в свой интернет-магазин, то ничего другого не останется, как только вручную выделить нужные данные и через буфер обмена перенести на свой сайт. И так придется делать каждый день. Неужели нет выхода?
Ручной разбор кода страниц неэффективенЕсли решать проблему «в лоб», то сразу напрашивается решение: программа (скрипт на сайте), которой надо данные, получает страницу от сервера как «обычный пользователь», разбирает (парсит) полученный html-код и выделяет из него нужную информацию. Это можно сделать или обычным регулярным выражением, или при помощи любого html-парсера. Сложность подхода — в его неэфективности. Во-первых, для получения небольшой порции данных (данные о валютах — это буквально десяток-другой символов) надо получать всю страницу, а это не менее нескольких десятков килобайт. Во-вторых, при любом изменении кода страницы, к примеру, дизайн поменялся или что-то еще, наш алгоритм разбора придется переделывать. Да и ресурсов это будет отбирать порядочно.
Веб-сервисы на SOAP — это перспективная технологияПоэтому разработчики пришли к решению — надо разработать какой-то универсальный механизм, который бы позволил прозрачно (на уровне протокола и среды передачи) и легко обмениваться данными между программами, которые могут находиться где угодно, быть написанными на любом языке и работать под управлением любой операционной системы и на любой аппаратной платформе. Такой механизм называют сейчас громкими терминами "Веб-сервисы" (web-service), «SOAP», «архитектура, ориентированная на сервисы» (service-oriented architecture). Для обмена данными используются открытые и проверенные временем стандарты — для передачи сообщений протокол HTTP (хотя можно использовать и другие протоколы — SMTP к примеру). Сами данные (в нашем примере — курсы валют) передаются упакованными в кросс-платформенный формат — в виде XML-документов. Для этого придуман специальный стандарт — SOAP.
Да, сейчас веб-сервисы, SOAP и XML у всех на слуху, их начинают активно внедрять и крупные корпорации вроде IBM и Microsoft выпускают новые продукты, призванные помочь тотальному внедрению веб-сервисов.
SOAP — часто очень громоздкое решениеНо! Для нашего примера с курсами валют, которые должны передаваться с сайта банка в движок интернет-магазина такое решение будет очень сложным. Ведь только описание стандарта SOAP занимает неприличные полторы тысячи страниц, и это еще не все. Для практического использования придется изучить еще работу со сторонними библиотеками и расширениями (только начиная с PHP 5.0 в него входит библиотека для работы с SOAP), написать сотни и тысячи строк своего кода. И все это для получения нескольких букв и цифр — явно очень тяжеловесно и нерационально.
Потому существует еще один, с натяжкой можно сказать альтернативный стандарт на обмен информацией — XML-RPC. Он был разработан при участии Microsoft компанией UserLand Software Inc и предназначен для унифицированной передачи данных между приложениями через Интернет. Он может заменить SOAP при построении простых сервисов, где не надо все «корпоративные» возможности настоящих веб-сервисов.
RPC — Remote Procedure Call — удаленный вызов процедурЧто же означает аббревиатура XML-RPC? RPC расшифровывается как Remote Procedure Call — удаленный вызов процедур. Это значит, что приложение (неважно, скрипт на сервере или обычное приложение на клиентском компьютере) может прозрачно использовать метод, который физически реализован и исполняется на другом компьютере. XML тут применяется для обеспечения универсального формата описания передаваемых данных. Как транспорт, для передачи сообщений применяется протокол HTTP, что позволяет беспрепятственно обмениваться данными через любые сетевые устройства — маршрутизаторы, фаерволы, прокси-сервера.
И так, для использования надо иметь: сервер XML-RPC, который предоставляет один или несколько методов, клиент XML-RPC, который может формировать корректный запрос и обрабатывать ответ сервера, а также знать необходимые для успешной работы параметры сервера — адрес, название метода и передаваемые параметры.
Вся работа с XML-RPC происходит в режиме "запрос-ответ", в этом и есть одно из отличий технологии от стандарта SOAP, где есть и понятия транзакций, и возможность делать отложенные вызовы (когда сервер сохраняет запрос и отвечает на него в определенное время в будущем). Эти дополнительные возможности больше пригодятся для мощных корпоративных сервисов, они значительно усложняют разработку и поддержку серверов, и ставят дополнительные требования к разработчикам клиентских решений.
Процедура работы с XML-RPC начинается с формирования запроса. Типичный запрос выглядит так:
POST /RPC2 HTTP/1.0
User-Agent: eshop-test/1.1.1 (FreeBSD)
Host: server.localnet.com
Content-Type: text/xml
Content-length: 172
<?xml version="1.0"?>
<methodCall>
<methodName>TestMetod</methodName>
<params>
<param>
<value><string>Привет, XML-RPC!</string></value>
</param>
</params>
</methodCall>
В первых строках формируется стандартный заголовок HTTP запроса POST. К обязательным параметрам относятся host, тип данных (MIME-тип), который должен быть text/xml, а также длина сообщения. Также в стандарте указывается, что поле User-Agent должно быть заполнено, но может содержать произвольное значение.
Далее идет обычный заголовок XML-документа. Корневой элемент запроса — <methodCall>, может быть только один, и не может содержать таких узлов в качестве дочерних. Это означает, что одним запросом можно вызвать только один метод на сервере.
Строка <methodName>TestMetod</methodName> указывает, что мы вызываем метод с именем TestMetod. При необходимости, тут можно указывать имя программы или модуля, содержащего метод, а также путь к нему. Спецификация XML-RPC хоть и налагает некоторые ограничения на набор символов, которыми может обозначаться метод, но как их интерпретировать — полностью зависит от реализации сервера.
Далее задаются передаваемые параметры. Для этого служит секция <params>, которая может содержать произвольное число подэлементов <param>, которые содержать параметр, описываемый тегом <value>. Параметры и типы данных мы рассмотрим чуть дальше. В нашем варианте методу передается один строковой параметр, заключенный в тег <string>.
После описания всех параметров следуют закрывающие теги. Запрос и ответ в XML-RPC это обычные документы XML, поэтому все теги обязательно должны быть закрыты. А вот одиночных тегов в XML-RPC нет, хотя в стандарте XML они присутствуют.
Tеперь разберем ответ сервера. Заголовок HTTP ответа обычный, если запрос успешно обработан, то сервер возвращает ответ HTTP/1.1 200 OK. Также как в запросе, следует корректно указать MIME-тип, длину сообщения и дату формирования ответа.
Само тело ответа следующее:
<?xml version="1.0"?>
<methodResponse>
<params>
<param>
<value><boolean>true</boolean></value>
</param>
</params>
</methodResponse>
Теперь вместо корневого тега <methodName> указывается тег <methodResponse>, в который вложены сразу результаты обработки запроса. К сожалению, в ответе не передается имя метода, поэтому вам следует его сохранить на стороне клиента, чтобы избежать путаницы, если одновременно вызываются различные методы.
Если при обработке вашего запроса произошла ошибка, то вместо <param> в ответе будет элемент <fault>, в котором будет вложена структура, описывающая ошибку. Описание ошибки содержит числовой код ошибки и ее текстовое описание.
А теперь рассмотрим кратко типы данных в XML-RPC. Всего типов данных есть 9 — семь простых типов и 2 сложных. Каждый тип описывается своим тегом или набором тегов (для сложных типов).
Существует 7 простых типов данных и 2 сложныхПростые типы:
Целые числа — тег <i4> или <int>;
Логический тип — тег <boolean>, может принимать как значения 0/1, так и true/false;
ASCII-строка — описывается тегом <string> и может содержать произвольную строку символов;
Числа с плавающей точкой — тег <double>, могут также содержать знак числа, дробная часть отделяется точкой;
Дата и время — описывается тегом <dateTime.iso8601> и должна соответствовать формату iso8601. Для дальнейшей обработки в скриптах такой формат немного неудобен, поэтому его всегда конвертируют при отправке/получении запроса. Это может делать специальная функция в составе библиотеки, или, если такой нет, разработчик должен конвертировать дату вручную.
Последним простым типом является строка, закодированная в base64, которая описывается тегом <base64>. Этот тип универсальный, с его помощью можно передавать любые данные между клиентом и сервером, хотя объем передаваемых данных из-за такой кодировки возрастает. Но это следствие текстовой природа протокола и формата XML в частности.
Сложные типы представлены структурами и массивами. Структура определяется корневым элементом <struct>, который может содержать произвольное количество элементов <member>, определяющих каждый член структуры. Член структуры описывается двумя тегами: первый, <name>, описывает имя члена, второй, <value>, содержит значение члена (вместе с тегом, описывающим тип данных).
Массивы не имеют именМассивы не имеют названий и описываются тегом <array>, который содержит один элемент <data>, и один или несколько дочерних элементов <value>, где задаются конкретные данные. Массив может содержать любые другие типы в произвольном порядке, а также другие массивы, что позволяет описывать многомерные массивы. Также можно описывать массив структур. Но то, что массив не имеет имени, усложняет в некоторых случаях его использование, для передачи сложных данных их приходится многократно упаковывать в другие типы (к примеру, чтобы передать несколько массивов, можно каждый массив отдельно упаковать в структуру, а потом создать один массив из этих структур).
Конечно, кто-то скажет, что такой перечень типов данных очень беден и «не позволяет развернуться». Да, если надо передавать сложные объекты, или большие объемы данных, то лучше использовать SOAP. А для небольших, нетребовательных приложений вполне подходит и XML-RPC, более того, очень часто даже его возможностей оказывается слишком много! Если учесть легкость развертывания, очень большое количество библиотек для почти любых языков и платформ, широкую поддержку в PHP, то XML-RPC часто просто не имеет конкурентов. Хотя сразу советовать его в качестве универсального решения нельзя — в каждом конкретном случае надо решать по обстоятельствах.
Ссылки по теме
- XML-RPC Home Page
- Specifications (перевод на русский)
- A list of public Web Services and specs that build on XML-RPC
- Реализации XML-RPC
- Пишем свой web-сервис на PHP и XML-RPC
Статья получена: hostinfo.ru