通过XML-RPC在Python访问Ruby对象?

3 投票
3 回答
1627 浏览
提问于 2025-04-11 18:53

我正在尝试通过 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 个回答

1

在一个支持的数据结构里返回一个空值(nil)也会导致内部服务器错误的提示。标准的 Ruby xmlrpc 服务器似乎不支持允许空值的 xmlrpc 扩展,尽管 Python 这边是支持的。xmlrpc4r 是支持空值的,但我还没试过。

1

XML-RPC 不能传递对象。可以使用的参数类型是有限的(正如 jakber 所说)。

5

你的客户端(在你的Python代码中是一个ServerProxy对象)只能接收一些特定类型的返回值,比如布尔值、整数、浮点数、数组、结构体、日期或者二进制数据。

但是,如果你不进行一些设置,它就无法返回另一个ServerProxy对象,而这个对象是你访问其他类所需要的。你可能可以在Ruby那边实现一个对象缓存,但这会涉及到跟踪活跃的会话,还要决定什么时候移除对象,如何处理缺失的对象等等。

所以,我建议你在Ruby那边创建一个简单的包装器,专门用来执行一些基本操作,比如:

def foobar()
  return ExampleFoo.new().foo().bar()
end

撰写回答