如何在Ruby中正确使用内置的XMLRPC?

时间:2012-02-16 10:07:19

标签: ruby xml-rpc

我正在尝试在Ruby 1.9中使用内置的XMLRPC。不幸的是,ruby-docs.org上没有记录XMLRPC,所以我尝试根据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 个答案:

答案 0 :(得分:7)

与阻止的另一种方式:

#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')

答案 1 :(得分:2)

你几乎是对的。这是您可以使用的tutorial。您的示例需要稍加修改,您必须将对象传递给将用于为RPC调用提供服务的add_handler:

# 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 :(得分:2)

请注意:默认的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'],

答案 3 :(得分:1)

我认为这有助于: 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!')