通过 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:
print s.example.test() 工作正常。
我不希望新的 ExampleBar 对象通过网络传输,但我希望它能够在服务器端“缓存”,并尊重随后对 bar() 的调用。
XML-RPC 可以支持这种用法还是太基础了?
所以我想我的问题确实是; 我怎样才能让它工作,如果不使用 XML-RPC 怎么办?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你的客户端(在Python代码中)是一个ServerProxy对象。 它只接受布尔型、整数、浮点型、数组、结构体、日期或二进制数据类型的返回值。
但是,如果不进行连接,它就无法返回另一个 ServerProxy,而您需要它来访问另一个类。 您可能可以在 Ruby 端实现一个对象缓存,但这需要跟踪活动会话并决定何时删除对象、如何处理丢失的对象等。
相反,我建议在 Ruby 端公开一个薄包装器,它可以原子操作,例如:
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:
XML-RPC 无法传递对象。 参数类型集是有限的(正如 jakber 所说)。
XML-RPC can't pass objects. The set of parameter types is limited (as jakber says).
在受支持的数据结构中返回 nil 也会导致内部服务器错误消息。 stdlib ruby xmlrpc 服务器似乎不支持允许 nils 的 xmlrpc 扩展,即使 python 端支持也是如此。 xmlrpc4r 支持 nils 但我还没有尝试过。
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.