Tornado中进行异步XML-RPC(客户端调用)

76 阅读2分钟

我想在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调用,可以按照以下步骤进行:

  1. 安装Twisted和tornado.platform.twisted:

    pip install twisted tornado.platform.twisted
    
  2. 在Tornado应用程序中导入Twisted和tornado.platform.twisted:

    import tornado.platform.twisted
    
    tornado.platform.twisted.install()
    
  3. 使用Twisted的Proxy类创建XML-RPC代理:

    from twisted.web.xmlrpc import Proxy
    
    proxy = Proxy('http://my_cobbler_server')
    
  4. 将代理传递给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)
    
  5. 将请求处理程序添加到Tornado应用程序:

    app = tornado.web.Application([
        (r"/", MyRequestHandler),
    ])
    
  6. 启动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方法,并将结果写入响应。此代码示例可以根据需要进行修改以满足您的特定需求。