XML-RPC в Ruby

Как известно, XML-RPC является достаточно распространенным методом вызова удаленных процедур, основанным на XML. Однако, несмотря на то, что он значительно проще, чем, например, SOAP, его использование все еще иногда достаточно сложно: необходимо сериализовать объекты в специальное XML-представление, затем распарсить полученный релзультат.

Однако, на самом деле, не все так плохо!

В стандартной библиотеке Ruby существует замечательная поддержка XML-RPC, о которой я немного расскажу далее.

Для создания простейшего клиента необходимо всего лишь подключить файл xmlrpc/client, создать объект клиента и вызывать функции RPC, как методы этого объекта. А возвращаемым значением метода является хэш выходных параметров.


  require 'xmlrpc/client'
  require 'pp'

  client = XMLRPC::Client.new2("http://xmlrpc-c.sourceforge.net/api/sample.php")
  result = client.call("sample.sumAndDifference", 5, 3)
  pp result

Это пример с сайта официальной документации. По идее, result должен представлять из себя хэш, в котором будут содержаться возвращаемые значения. Однако, этот пример не работает (как минимум у меня). При вызове он выдает исключение:

/usr/lib/ruby/1.8/xmlrpc/client.rb:555:in `do_rpc': Wrong content-type (received 'text/html' but expected 'text/xml'):  (RuntimeError)

Что же не так? Сервер, к которому обращается клиент почему-то возвращает в заголовке Content-Type значение text/html, хотя ожидается text/xml. Вообще говоря, это стоит считать багом настройки сервера, но если Вы осуществляете запросы к каким-то внешним сервисам, есть вероятность, что какой-то из них так же будет отсылать некорректный Content-Type.

Первое что мне пришло в голову - это отключить проверку в клиенте. Самый простой способ не требует никакой модификации кода библиотеки. Для этого перед использованием клиента необходимо поместить следующий код:


  XMLRPC::Client.class_eval do
    def parse_content_type(a)
      ['text/xml']
    end
  end

То есть мы просто подменяем метод parse_content_type с тем, чтобы он всегда возвращал text/xml. Теперь можно спокойно делать запросы к различным сервисам и вышеприведенный пример выведет что-то вроде:


{"sum"=>8, "difference"=>2}

Теперь можно использовать библиотеку для работы сразличными XML-RPC сервисами в сети.

Ссылки

 Подписаться на RSS

 #  #  #  #  #  #  #  #  #  #

Добавить комментарий