Как правильно использовать встроенный XMLRPC в Ruby? - PullRequest
1 голос
/ 16 февраля 2012

Я пытаюсь использовать встроенный XMLRPC в Ruby 1.9. К сожалению, XMLRPC не задокументирован на ruby-docs.org, поэтому я попытался создать тестовый код на основе примеров, найденных Google:

# Server.rb
require "xmlrpc/server"
server = XMLRPC::Server.new( 1234 )
server.add_handler( "test" ) { |msg| return "responce for #{msg}" }
server.serve()

# Client.rb

require "xmlrpc/client"
server = XMLRPC::Client.new( "localhost", "/", 1234 )
server.call( "test", 42 ) == "responce for 42"

К сожалению, это не работает как в Windows, так и в OSX. Server.rb завершается с загадочной ошибкой:

C:/Ruby193/lib/ruby/1.9.1/xmlrpc/client.rb:414:in `call': Uncaught exception unexpected return in method test (XMLRPC::FaultException)
        from client.rb:6:in `<main>'

Может кто знает в чем моя ошибка?

Ответы [ 4 ]

7 голосов
/ 16 февраля 2012

Другой способ с блоком:

#server.rb:
require "xmlrpc/server"
server = XMLRPC::Server.new( 1234 )
server.add_handler('my_test.test') { |msg|"responce for #{msg}" }

#client.rb
require "xmlrpc/client"
client = XMLRPC::Client.new( "localhost", "/", 1234 )
s = client.call('my_test.test','asd')
3 голосов
/ 16 февраля 2012

Вы поняли это почти правильно.Вот учебник , который вы можете использовать.Ваш пример нуждается в небольшой модификации, вы должны передать объект add_handler, который будет использоваться для обслуживания ваших вызовов RPC:

# server.rb
require "xmlrpc/server"

class MyClass
  def dosomething(a)
    "response for #{a}"
  end
end

server = XMLRPC::Server.new( 1234 )
server.add_handler( "test", MyClass.new )
server.serve

# client.rb
require "xmlrpc/client"
server = XMLRPC::Client.new( "localhost", "/", 1234 )
puts server.call( "test.dosomething", 42 ) == "response for 42"
2 голосов
/ 28 мая 2012

Обратите внимание: по умолчанию xmlrpc / client.rb impl.не поддерживает клиентские сертификаты на основе соединений https.Если вы хотите, вы должны использовать другой lib или патч client.rb с чем-то вроде:

# HG changeset patch
# User Anonymous Coward <anonymous@gmail.com>
# Date 1338149770 -10800
# Node ID f0557306c8e4f113507fb3bab8567391949fa302
# Parent  3eae8e8f9e065ff6cdf1c95092ad5cca635c9eac
patch client.rb to support https with client certificate.

diff -r 3eae8e8f9e06 -r f0557306c8e4 client.rb
--- a/client.rb Sun May 27 22:20:18 2012 +0300
+++ b/client.rb Sun May 27 23:16:10 2012 +0300
@@ -292,8 +292,8 @@

     # Constructors -------------------------------------------------------------------

-    def initialize(host=nil, path=nil, port=nil, proxy_host=nil, proxy_port=nil, 
-                   user=nil, password=nil, use_ssl=nil, timeout=nil)
+    def initialize(host=nil, path=nil, port=nil, proxy_host=nil, proxy_port=nil,
+        user=nil, password=nil, use_ssl=nil, timeout=nil, cacert=nil, cert=nil, key=nil)

       @http_header_extra = nil
       @http_last_response = nil 
@@ -311,6 +311,10 @@
       if use_ssl
         require "net/https"
         @port = port || 443
+        @cacert = cacert
+        @cert = cert
+        @key = key
+
       else
         @port = port || 80
       end
@@ -325,8 +329,19 @@

       # HTTP object for synchronous calls
       Net::HTTP.version_1_2
-      @http = Net::HTTP.new(@host, @port, @proxy_host, @proxy_port) 
-      @http.use_ssl = @use_ssl if @use_ssl
+      @http = Net::HTTP.new(@host, @port, @proxy_host, @proxy_port)
+      if @use_ssl
+        @http.use_ssl = @use_ssl
+        if nil != @cacert
+          @http.ca_file = @cacert
+          @http.verify_mode = OpenSSL::SSL::VERIFY_PEER
+          @http.verify_depth = 5
+        else
+          @http.verify_mode = OpenSSL::SSL::VERIFY_NONE
+        end
+        @http.cert = @cert
+        @http.key = @key
+      end
       @http.read_timeout = @timeout
       @http.open_timeout = @timeout

@@ -366,7 +381,7 @@
       hash.each { |k,v| h[k.to_s.downcase] = v }

       self.new(h['host'], h['path'], h['port'], h['proxy_host'], h['proxy_port'],     h['user'], h['password'],
1 голос
/ 16 февраля 2012

Я думаю, что это может помочь: http://www.ntecs.de/ruby/xmlrpc4r/howto.html

#server.rb
require "xmlrpc/server"
server = XMLRPC::Server.new( 1234 )

class MyHandler
  def test(msg)
        "message #{msg}"
    end
end
server.add_handler(XMLRPC::iPIMethods("my_test"), MyHandler.new)
server.serve

#client.rb
require "xmlrpc/client"
server = XMLRPC::Client.new( "localhost", "/", 1234 )
s = server.call('my_test.test','hello!')
...