views:

660

answers:

3

Hello

I am trying to export a Ruby framework via XML-RPC. However I am having some problems when trying to call a method from a class not directly added as a handler to the XML-RPC server. Please see my example below:

I have a test Ruby XML-RPC server as follows:

require "xmlrpc/server"

class ExampleBar
  def bar()
    return "hello world!"
  end
end

class ExampleFoo
  def foo()
    return ExampleBar.new
  end

  def test()
    return "test!"
  end
end

s = XMLRPC::Server.new( 9090 )

s.add_introspection

s.add_handler( "example", ExampleFoo.new )

s.serve

And I have a test Python XML-RPC Client as follows:

import xmlrpclib

s = xmlrpclib.Server( "http://127.0.0.1:9090/" )

print s.example.foo().bar()

I would expect the python client to print "hello world!" as it is the equivalent of the following ruby code:

example = ExampleFoo.new
puts example.foo().bar()

However it generates an error: "xmlrpclib.ProtocolError: <ProtocolError for 127.0.0.1:9090/: 500 Internal Server Error>".

print s.example.test() works fine.

I dont expect the new ExampleBar object to go over the wire but I would expect it to be 'cached' server side and the subsequent call to bar() to be honoured.

Can XML-RPC support this kind of usage or is it too basic?

So I guess my question really is; how can I get this working, if not with XML-RPC what with?

+3  A: 

Your client (s in you Python code) is a ServerProxy object. It only accepts return values of type boolean, integers, floats, arrays, structures, dates or binary data.

However, without you doing the wiring, there is no way for it to return another ServerProxy, which you would need for accessing another class. You could probably implement an object cache on the Ruby side, but it would involve keeping track of active session and deciding when to remove objects, how to handle missing objects, etc.

Instead I would suggest exposing a thin wrapper on the ruby side that does atomic operations like:

def foobar()
  return ExampleFoo.new().foo().bar()
end
jakber
Thanks Jakber, I was hoping to avoid a wrapper though, as the real code I am working with is large and very OO so lots of sub/super classes. I was hoping ruby introspection would save the day! :)
QAZ
A: 

XML-RPC can't pass objects. The set of parameter types is limited (as jakber says).

Martin v. Löwis
A: 

Returning a nil inside of a supported data structure will also cause an Internal Server Error message. The stdlib ruby xmlrpc server does not appear to support the xmlrpc extensions which allow nils, even though the python side does. xmlrpc4r supports nils but I haven't tried it yet.

Kevin Martin