通过XML-RPC在Python访问Ruby对象?
我正在尝试通过 XML-RPC 导出一个 Ruby 框架。不过,当我试图调用一个没有直接添加为 XML-RPC 服务器处理程序的类的方法时,遇到了一些问题。下面是我的例子:
我有一个测试用的 Ruby XML-RPC 服务器,如下所示:
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
还有一个测试用的 Python XML-RPC 客户端,如下所示:
import xmlrpclib
s = xmlrpclib.Server( "http://127.0.0.1:9090/" )
print s.example.foo().bar()
我本来希望 Python 客户端能打印出 "hello world!",因为这相当于以下 Ruby 代码:
example = ExampleFoo.new
puts example.foo().bar()
然而,它却产生了一个错误:“xmlrpclib.ProtocolError: <ProtocolError for 127.0.0.1:9090/: 500 Internal Server Error>”。
使用 print s.example.test() 是可以正常工作的。
我并不指望新的 ExampleBar 对象会被传输到客户端,但我希望它能在服务器端被“缓存”,然后后续对 bar() 的调用能够正常执行。
XML-RPC 能支持这种用法吗,还是说它太基础了?
所以我想问的是;如果用 XML-RPC 不能实现,那我该用什么呢?
3 个回答
在一个支持的数据结构里返回一个空值(nil)也会导致内部服务器错误的提示。标准的 Ruby xmlrpc 服务器似乎不支持允许空值的 xmlrpc 扩展,尽管 Python 这边是支持的。xmlrpc4r 是支持空值的,但我还没试过。
XML-RPC 不能传递对象。可以使用的参数类型是有限的(正如 jakber 所说)。
你的客户端(在你的Python代码中是一个ServerProxy对象)只能接收一些特定类型的返回值,比如布尔值、整数、浮点数、数组、结构体、日期或者二进制数据。
但是,如果你不进行一些设置,它就无法返回另一个ServerProxy对象,而这个对象是你访问其他类所需要的。你可能可以在Ruby那边实现一个对象缓存,但这会涉及到跟踪活跃的会话,还要决定什么时候移除对象,如何处理缺失的对象等等。
所以,我建议你在Ruby那边创建一个简单的包装器,专门用来执行一些基本操作,比如:
def foobar()
return ExampleFoo.new().foo().bar()
end