Я пытаюсь экспортировать фреймворк Ruby через XML-RPC. Однако у меня возникают некоторые проблемы при попытке вызвать метод из класса, который напрямую не добавлен в качестве обработчика на сервер 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 напечатает «привет, мир!» поскольку это эквивалент следующего рубинового кода:
example = ExampleFoo.new
puts example.foo().bar()
Однако он генерирует ошибку: «xmlrpclib.ProtocolError: <ProtocolError для 127.0.0.1:9090/: 500 Internal Server Error>».
print s.example.test () отлично работает.
Я не ожидаю, что новый объект ExampleBar пройдет по сети, но я ожидаю, что это будет «кэшированная» серверная часть, и последующий вызов bar () будет соблюден.
Может ли XML-RPC поддерживать такое использование или это слишком просто?
Так что я думаю, что мой вопрос действительно таков; как я могу заставить это работать, если не с XML-RPC, с чем?






Ваш клиент (в вашем коде Python) является объектом ServerProxy. Он принимает только возвращаемые значения типа boolean, целые числа, числа с плавающей запятой, массивы, структуры, даты или двоичные данные.
Однако, если вы не выполните проводку, он не сможет вернуть другой ServerProxy, который вам понадобится для доступа к другому классу. Вероятно, вы могли бы реализовать кеш объектов на стороне Ruby, но это потребовало бы отслеживания активного сеанса и принятия решения о том, когда удалять объекты, как обрабатывать отсутствующие объекты и т. д.
Вместо этого я бы предложил выставить тонкую оболочку на рубиновой стороне, которая выполняет атомарные операции, такие как:
def foobar()
return ExampleFoo.new().foo().bar()
end
XML-RPC не может передавать объекты. Набор типов параметров ограничен (как говорит jakber).
Возврат nil внутри поддерживаемой структуры данных также вызовет сообщение об ошибке внутреннего сервера. Сервер stdlib ruby xmlrpc, похоже, не поддерживает расширения xmlrpc, которые допускают nils, хотя сторона python поддерживает. xmlrpc4r поддерживает nils, но я еще не пробовал.
Спасибо, Jakber, я надеялся избежать обертки, поскольку реальный код, с которым я работаю, большой и очень объектно ориентированный, поэтому много подклассов / суперклассов. Я надеялся, что рубиновый самоанализ спасет положение! :)