我想在Tornado中向Cobbler服务器进行异步XML-RPC(客户端调用),类似于以下示例:
cobbler_connection = xmlrpclib.Server("http://my_cobbler_server")
...
profile = yield gen.Task(cobbler_connection.get_profile, profile_name)
...
现在我正在使用xmlrpclib,它似乎不会进行异步客户端调用,因此最终会阻塞Tornado(或者我听说过)。我对Tornado和一般异步编程都很陌生(但请不要给我任何说明或初学者指南的链接)。我尝试过谷歌搜索,但无法清楚地了解需要对xmlrpclib做出哪些更改以便能够异步进行这些调用。任何提示都将不胜感激。提前谢谢。
解决方案
使用Tornado进行异步XML-RPC调用的一种方法是使用Twisted库。Twisted是一个异步网络库,可以与Tornado一起使用。要使用Twisted进行XML-RPC调用,可以按照以下步骤进行:
-
安装Twisted和tornado.platform.twisted:
pip install twisted tornado.platform.twisted -
在Tornado应用程序中导入Twisted和tornado.platform.twisted:
import tornado.platform.twistedtornado.platform.twisted.install() -
使用Twisted的Proxy类创建XML-RPC代理:
from twisted.web.xmlrpc import Proxy proxy = Proxy('http://my_cobbler_server') -
将代理传递给Tornado RequestHandler:
class MyRequestHandler(tornado.web.RequestHandler): def get(self): # 调用XML-RPC方法 proxy.callRemote('my_method', arg1, arg2).addCallbacks(self.on_success, self.on_error) def on_success(self, result): # 处理成功的XML-RPC调用 self.write(result) def on_error(self, error): # 处理失败的XML-RPC调用 self.write('error: %s' % error) -
将请求处理程序添加到Tornado应用程序:
app = tornado.web.Application([ (r"/", MyRequestHandler), ]) -
启动Tornado应用程序:
app.listen(8000) tornado.ioloop.IOLoop.instance().start()
使用Twisted进行XML-RPC调用可以确保这些调用不会阻塞Tornado应用程序。这意味着应用程序可以继续处理其他请求,而无需等待XML-RPC调用的结果。
代码例子
下面是一个使用Twisted进行异步XML-RPC调用的完整代码示例:
import tornado.httpserver
import tornado.ioloop
import tornado.web
import tornado.platform.twisted
tornado.platform.twisted.install()
from twisted.web.xmlrpc import Proxy
from twisted.internet import reactor
proxy = Proxy('http://my_cobbler_server')
from tornado.options import define, options
define("port", default=8000, help="run on the given port", type=int)
class MyRequestHandler(tornado.web.RequestHandler):
def get(self):
# 调用XML-RPC方法
proxy.callRemote('my_method', arg1, arg2).addCallbacks(self.on_success, self.on_error)
def on_success(self, result):
# 处理成功的XML-RPC调用
self.write(result)
def on_error(self, error):
# 处理失败的XML-RPC调用
self.write('error: %s' % error)
if __name__ == "__main__":
tornado.options.parse_command_line()
app = tornado.web.Application([
(r"/", MyRequestHandler),
])
http_server = tornado.httpserver.HTTPServer(app)
http_server.listen(options.port)
tornado.ioloop.IOLoop.instance().start()
此代码示例演示了如何使用Twisted进行异步XML-RPC调用。它创建了一个XML-RPC代理,并将其传递给Tornado RequestHandler。当请求处理程序收到请求时,它将调用XML-RPC方法,并将结果写入响应。此代码示例可以根据需要进行修改以满足您的特定需求。