2004 г.
XML-RPC: вызов процедур посредством XML
Александр Лозовюк, Издательский
Дом "КОМИЗДАТ"
RPC расшифровывается как Remote Procedure Call - удаленный вызов процедур с помощью
XML. Как же работает XML-RPC и каковы его отличия от стандарта SOAP?
На сцене - XML-RPC
RPC - удаленный вызов процедур с помощью XML. Сама методика удаленного вызова процедуры
известна давно и используется в таких технологиях, как DCOM, SOAP, CORBA. RPC предназначен
для построения распределенных клиент-серверных приложений. Это дает возможность строить
приложения, которые работают в гетерогенных сетях, например на компьютерах различных систем,
производить удаленную обработку данных и управление удаленными приложениями.
Приведем сильно упрощенный пример. Приложение, выполняя обработку некоторых данных
на локальной машине, обращается к некоторой процедуре. Если ее реализация присутствует
в программе, то процедура (функция) принимает параметры, выполняет действие и возвращает
некоторые данные. Если это удаленный вызов, мы должны знать, где будет исполняться наша
процедура. Запрос на выполнение процедуры вместе с параметрами записывается в виде XML-документа
и посредством HTTP передается по сети на другой компьютер, где из XML-документа извлекается
имя процедуры, параметры и прочая нужная информация. После завершения работы процедуры
формируется ответ (например, возвращаемые данные) - и он передается компьютеру, пославшему
запрос. Заметим, что для прикладной программы все действия совершенно прозрачны.
По этому принципу функционируют все системы, и различия в реализации и процедуре обмена
не оказывают существенного влияния на его суть.
Хорошо, предположим, у нас есть возможность удаленно вызывать процедуры и функции -
чего же нам еще? А вот чего. Формат обмена данными при классической модели RPC (DCOM,
CORBA) остается бинарным - а значит, работать с ним сложнее, он не слишком подходит, если
надо организовать работу распределенной системы, где между отдельными участками сети стоят
firewall/прокси-серверы. Технология DCOM, например, реализована для Windows-систем, CORBA
функционирует на разных платформах, но наиболее полноценна ее реализация на J2EE. Значит,
всегда найдется (и действительно находится) такая конфигурация сети/платформ, чтобы для
реализации распределенной системы в ней ни одна технология не подходила. Так что же делать?
Задавшись этим вопросом, компания UserLand Software Inc. создала технологию
XML-RPC. Основным транспортом в ней является протокол HTTP; формат данных - XML. Это снимает
ограничения, налагаемые как на конфигурацию сети, так и на маршрут следования пакетов,-
вызовы XML-RPC представляют собой простой тип данных text/xml и свободно проходят сквозь
шлюзы везде, где допускается ретрансляция http-трафика.
У новой технологии есть и другие преимущества. Применение XML для описания данных позволило
упростить программные средства создания распределенных приложений, снизились требования
к клиенту и серверу. Например, теперь есть возможность связать веб-планшет с сервером
на работе и с домашним компьютером. Программы разбора (парсинга) XML сейчас существуют
практически для всех операционных систем и на всех языках программирования - следовательно,
препятствий для внедрения технологии вроде бы нет.
Что же это такое?
Рассмотрение XML-RPC проведем на упрощенном тестовом примере. Для снижения затрат мы
разворачиваем систему, где на один компьютер (сервер) ставится мощное ПО для перевода,
проверка синтаксиса и грамматики, а все клиенты обращаются к нему посредством XML-RPC.
(Конечно, этот пример выдуман, чтобы легче было познакомить читателя с технологией - но,
господа программисты, кто мешает реально сделать такую систему?)
Сообщение XML-RPC передается методом POST-протокола HTTP. Сообщения бывают трех типов:
запрос, ответ и сообщение об ошибке.
Запрос |
XML-RPC запрос |
Описание |
POST /RPC2 HTTP/1.0
User-Agent: MyAPP-Word/5.1.2 (WinNT)
Host: server.localnet.com
Content-Type: text/xml
Content-length: 172
<? xml version="1.0"?>
<methodCall>
<methodName>CheckWord</methodName>
<params>
<param>
<value><string>проверка</string></value>
</param>
</params>
</methodCall> |
Сначала идет стандартный заголовок http-запроса. MIME-тип данных должен быть text/xml,
длина также обязательно должна присутствовать и иметь корректное значение, равное длине
передаваемого сообщения.
Стандартный заголовок любого корректного XML-документа.
Корневой узел. Не допускается вложенности тегов <methodCall> - значит, одним запросом
мы можем вызвать только один метод.
Тег <methodName> указывает на объект и название метода, который вызывается. Можно
указывать так, как принято в языках программирования вызывать свойства класса: имя метода
- через точку после имени класса. Можно также передавать пути и имя программы. Мы вызываем
метод CheckWord объекта OrfoCheck.
В секции <params> задаются параметры, которые передаются в метод. Секция может содержать
произвольное число подэлементов <param>, содержащих параметр, который описывается
тегом <value>. Параметры и типы данных мы рассмотрим чуть дальше. В нашем варианте
методу передается один параметр, слово (оно заключено в тег <string>), которое надо
проверить на правильность написания.
Все теги, согласно спецификации XML, должны иметь соответствующие закрывающие элементы
- в XML-RPC нет одиночных тегов. |
Типы данных
В протоколе XML-RPC предусмотрено семь простых типов данных и два сложных, для передачи
параметров методу и возвращаемых значений. Эти типы отображают основные типы данных реальных
языков программирования. Более сложные типы, такие, например, как объекты, нужно передавать
в двоичном виде или заменять структурами.
Целые числа - задаются тегом <i4> или <int> и представляются 4-байтовыми
целыми числами со знаком. Для задания отрицательных чисел ставится знак "-", например
34, 344, -15.
Логический тип данных представляется тегом <boolean> и может иметь значения 0
(false) или 1 (true). Можно использовать как 1/0, так и символьные константы true/false.
ASCII-строка - тип данных, принимаемый по умолчанию. Представляет собой просто строку
символов, заключенную в теги <string></string>. В качестве символов нельзя
использовать служебные знаки "<" и "&" - их следует передавать кодами <
и & соответственно.
Числа с плавающей точкой. Задаются тегом <double> и представляют собой числа
с плавающей точкой двойной точности. Как разделитель целой и дробной части используется
знак ",". Пробелы недопустимы. Отрицательные числа задаются знаком "-" перед числом.
Дата/время. Для передачи времени/даты служит тег <dateTime.iso8601>. Пример времени
- 19980717T14:08:55 (в спецификации написано, что сервер сам должен определять, как посылать
время/дату. Использовать этот тип данных, пользоваться структурой или же просто передавать
дату как строку не рекомендуется).
Двоичные данные передаются в закодированном (base64) виде и описываются тегом <base64>.
Структуры. Для передачи структурированных данных можно конструировать свои структуры.
Структура определяется корневым элементом <struct>, который может содержать произвольное
количество элементов <member>, определяющих каждый член структуры. Член структуры
описывается двумя тегами: первый, <name>, описывает имя члена, второй, <value> содержит
значение члена (вместе с тегом, описывающим тип данных). Например, так описывается структура
с двух строковых элементов:
<struct>
<member>
<name>FirstWord</name>
<value><string>Hell</string></value>
</member>
<member>
<name>SecondWord</name>
<value><string>World!</string></value>
</member>
</struct>
Массивы. Массивы не имеют названия и описываются тегом <array>. Он содержит один
элемент <data> и один или несколько дочерних элементов <value>, где задаются
данные. В качестве элементов массива могут выступать любые другие типы в произвольном
порядке, а также другие массивы - что позволяет описывать многомерные массивы. Так же
можно описывать массив структур. Пример 4-элементного массива:
<array>
<data>
<value><i4>34</i4></value>
<value><string>Привет, Мир!</string></value>
<value><boolean>0</boolean></value>
<value><i4>-34</i4></value>
</data>
</array>
Ответ сервера |
XML-RPC ответ |
Описание |
HTTP/1.1 200 OK
Connection: close
Content-Length: 166
Content-Type: text/xml
Date: Fri, 17 Jul 1998 19:55:08 GMT
Server: MyWordCheckSerwer/5.1.2-WinNT
<? xml version="1.0"?>
<methodResponse>
<params>
<param>
<value><boolean>true</boolean></value>
</param>
</params>
</methodResponse>
Тело ответа при ошибке приложения
<fault>
<value>
<struct>
<member>
<name>faultCode</name>
<value><int>4</int></value>
</member>
<member>
<name>faultString</name>
<value>
<string>Too many рarameters.</string>
</value>
</member>
</struct>
</value>
</fault> |
Сначала идет стандартный заголовок http-ответа сервера. MIME-тип данных должен быть
text/xml, длина также должна обязательно присутствовать и иметь корректное значение, равное
длине передаваемого сообщения.
Стандартный заголовок любого корректного XML-документа.
Корневой узел. Не допускается вложенности тегов <methodResponse>.
Теги <params> и <param> аналогичны запросу и включают один или более элементов <value>,
которые содержат значение, возвращенное методом.
Если сервер отвечает HTTP-кодом 200 ОК - это значит, что запрос успешно обработан. Он
уведомляет лишь о том, что данные по сети переданы правильно и сервер сумел их корректно
обработать. Но метод также может вернуть ошибку - и это уже будет ошибка не протокола,
а логики приложения.
В таком случае передается сообщение и структура, которая описывает код ошибки и текстовое
объяснение.
В нашем примере передается структура из двух элементов: первый элемент содержит целочисленный
код ошибки (4), второй элемент - текстовая строка, описывающая ошибку (Too many рarameters
- неправильное число параметров). |
Окончательный вариант
Теперь можно окончательно описать работу нашего тестового примера. Итак, приложение
MyAppWord (текстовый редактор) хочет перевести на английский, например, слово "world".
Программа формирует запрос к серверу, вызывая процедуру перевода TranslateWord. Процедуре
передается структура, содержащая слово, которое следует перевести, и направление перевода,
которое задается символьной строкой - "en-ru".
MyAppWord
Запрос:
POST /RPC2 HTTP/1.0
User-Agent: MyAppWord/5.1.2 (WinNT)
Host: server.localnet.com
Content-Type: text/xml
Content-length: 172
<? xml version="1.0"?>
<methodCall>
<methodName>TranslateWord</methodName>
<params>
<param>
<value>
<struct>
<member>
<name>Word</name>
<value><string>world</string></value>
</member>
<member>
<name>typetranslate</name>
<value><string>en-ru</string></value>
</member>
</struct>
</param>
</params>
</methodCall>
Сервер, приняв наш запрос, передает его программе-демону, которая производит парсинг
запроса, выделяет из него нужные данные и, найдя (например, по таблице) ссылку на нужный
метод, вызывает его с переданными параметрами. Если тип и количество параметров правильные,
то по окончании работы метода программа-демон принимает возвращенное значение, преобразует
его в XML-описание и формирует ответ.
MyAppWord
Ответ:
HTTP/1.1 200 OK
Connection: close
Content-Length: 166
Content-Type: text/xml
Date: Fri, 17 Jul 1998 19:55:08 GMT
Server: MyWordCheckSerwer/5.1.2-WinNT
<? xml version="1.0"?>
<methodResponse>
<params>
<param>
<struct>
<member>
<name>WordtoTranslate</name>
<value><string>world</string></value>
</member>
<member>
<name>translatesword</name>
<value><string>мир</string></value>
</member>
<member>
<name>typetranslate</name>
<value><string>en-ru</string></value>
</member>
</struct>
</param>
</params>
</methodResponse>
MyAppWord
Сообщение об ошибке:
HTTP/1.1 200 OK
Connection: close
Content-Length: 166
Content-Type: text/xml
Date: Fri, 17 Jul 1998 19:55:08 GMT
Server: MyWordCheckSerwer/5.1.2-WinNT
<? xml version="1.0"?>
<methodResponse>
<fault>
<value>
<struct>
<member>
<name>faultCode</name>
<value><int>10</int></value>
</member>
<member>
<name>faultString</name>
<value>
<string>Перевод невозможен. Слово отсутствует в словаре.</string>
</value>
</member>
</struct>
</value></fault> </methodResponse>
Приложение получит такое сообщение, когда запрос на перевод не может быть удовлетворен,
поскольку слова нет в словаре.
Хотя наш пример, на первый взгляд, кажется надуманным и простым, тем не менее, на нем
показано, как можно уже сегодня использовать XML-RPC для решения конкретных задач. Конечно,
его возможности намного шире, и можно, например, представить себе распределенную ОС, построенную
на XML-RPC, или системы визуализации данных, построенные по архитектуре X Window, но с
применением все того же XML-RPC.
XML-RPC vs SOAP
Если для реализации удаленного вызова вы используете XML, то у вас есть выбор: использовать
XML-RPC или же SOAP (Simple Object Access Protocol). О последней уже написано множество
статей, поэтому предлагаем только сравнить обе технологии.
Вот некоторые характеристики, которые определяют различия XML-RPC или же SOAP:
Характеристика |
XML-RPC |
SOAP |
Скалярные типы данных |
+ |
+ |
Структуры |
+ |
+ |
Массивы |
+ |
+ |
Именованные массивы и структуры |
- |
+ |
Определяемые разработчиком кодировки |
- |
+ |
Определяемые разработчиком типы данных |
- |
+ |
Детализация ошибок |
+ |
+ |
Легкость освоения и практического применения |
+ |
- |
Конечно, на первый взгляд "минус" в столбце SOAP встречается только единожды. Это создает
иллюзию "всереализуемости всего" в нем. Но давайте присмотримся внимательнее. Основные
типы данных у обоих конкурентов одинаковые. Но в XML-RPC отсутствует возможность задавать
имена для массивов и структур (все структуры и массивы являются "анонимными"). Возможно,
это упущение разработчиков, но решить эту проблему можно и самому, например вводя еще
одну строковую переменную с именем массива или структуры (в случае, если таких объектов
много, можно завести специальный массив "имен массивов").
С "определяемыми разработчиком кодировками" ситуация уже серьезнее. Сам механизм подобного
ограничения не совсем ясен - ни стандарт XML, ни, тем более, транспортный уровень (протокол
HTTP) таких ограничений не имеют. Да и стремление сделать клиент/сервер XML-RPC как можно
более простым тоже не привело бы к возникновению подобного ограничения. Хотя, с другой
стороны, SOAP тоже не блещет поддержкой кодировок (US-ASCII, UTF-8, UTF-16). Правда, в
обеих технологиях есть возможность обойти все эти недостатки сразу - тип данных base64.
Но выход ли это?
Посмотрим теперь на пункт "легкость в освоении и применении". В свете сегодняшних темпов
развития технологий и стандартов, особенно Web, этот пункт приобретает большую важность.
Реальна ситуация, когда крупный проект начинает разрабатываться на самой передовой основе
- а в конце работы новый стандарт не только "уже не новый", но и "уже не стандарт вообще".
Недавно W3C опубликовала черновой вариант SOAP Version 1.2 - поверьте, и объем, и сложность
документации впечатляют. Трудности возникают даже на этапе ознакомительного чтения, не
говоря уже о разработке. А вот спецификация XML-RPC занимает около трех страниц А4 и предельно
проста.
Да, ни одна из этих технологий не является панацеей от всех бед и не претендует на
полноту. Большинство программистов и разработчиков спецификаций сходятся на том, что:
- если вам нужна система для работы со сложной логикой, если вы передаете большие комплексные
структуры данных, если вам нужна полная информация о клиенте, если вы хотите, чтобы запрос
содержал в себе инструкции по его обработке, и, наконец, если для вас важно, чтобы за
стандартом стояли гранды индустрии (Microsoft, IBM, Sun) - вам следует остановить свой
выбор на SOAP;
- если же данные являются относительно простыми, а приложения должны работать на множестве
платформ и на разных языках, если важна скорость работы и логика системы не нуждается
в сложных командах - используйте XML-RPC.
Выбрав SOAP, сразу смиритесь с тем, что у вашей команды разработчиков (или у вас самих)
впереди много головной боли, которая начнется уже с момента чтения спецификаций. Но ведь
зато вы будете иметь возможность в конце концов построить систему практически любой сложности
и функциональности.
Если выберете XML-RPC - написать программу клиента/сервера не составит труда даже начинающему
программисту. Да и о выборе ПО можете не задумываться - хоть Borland Delphi/Kylix, хоть
Phyton. Но не все задачи будут решаться сразу, а некоторые не будут решаться вообще.
Заключение
Не трудно увидеть, что стандарт XML-RPС очень прост - и в то же время применение XML
как основного инструмента для описания данных позволяет сделать его очень гибким. Протокол
можно модифицировать под каждую конкретную задачу, а использование хорошо зарекомендовавших
себя стандартов на передачу данных (HTTP/HTTPS) позволяет успешно применять его на любых
платформах, где имеется его поддержка.
Ссылки для разработчиков
Реализации XML-RPC существуют для множества платформ и языков
программирования. Вот ссылки на наиболее интересные компоненты для:
Большой
список реализаций XML-RPC.
Кроме того, постоянно пополняется
список публичных
XML-RPC-сервисов.
Одними из наиболее известных проектов, использующих XML-RPC, являются
Mozilla и
Apache.
Для лучшего понимания технологии XML-RPC существует хорошо составленное
xmlrpc-howto,
а также статья
"XML-RPC
for Newbies".